Compare commits

..

38 Commits

Author SHA1 Message Date
Johan Hedberg
2bd062c258 release: bump version to Zephyr 2.2.1
Update version to 2.2.1

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2020-05-29 11:50:11 +03:00
Johan Hedberg
d2160cbf4a doc: releases: Add release notes for Zephyr 2.2.1
Add the release notes for Zephyr 2.2.1.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2020-05-29 11:50:11 +03:00
David Brown
9a3aa3c9c3 updatehub: Require peer verification with DTLS
DTLS without peer verification offers no security whatsoever (and is
arguably worse than not using DTLS in the first place).

Change the verification option to require this peer verification.  To
use this, it may be necessary to install and use a root certificate.

Signed-off-by: David Brown <david.brown@linaro.org>
2020-05-28 22:28:36 +03:00
François Delawarde
137ebbc43f bluetooth: host: fix wrong bt/cf settings loading
This commits fixes the loading of bt/cf settings into memory. Only data
was loaded and not the address.

Signed-off-by: François Delawarde <fnde@demant.com>
2020-05-27 12:37:37 +03:00
Andries Kruithof
a520506076 Bluetooth: controller: split: Update feature exchange to BTCore V5.0
The existing feature exchange procedure does not give the proper
response as specified in the BT core spec 5.0.
The old behaviour is that the feature-response returns the logical and
of the features for both peers.
The behaviour implemented here is that the feature-response returns the
featureset of the peer, except for octet 0 which is the logical and of
the supported features.
Tested by using the bt shell, and having different featuresets
on the 2 peers.

This fixes #25483

Signed-off-by: Andries Kruithof <Andries.Kruithof@nordicsemi.no>
2020-05-27 12:37:04 +03:00
Vinayak Kariappa Chettimada
2758c33e39 Bluetooth: controller: split: Fix slave latency cancel race
Fix missing transmit buffer demutiplexing before checking if
slave latency needs to be maintained or cancelled.

This bug was detected when new transmit buffer was enqueued
overlapping with on-air radio transmission of empty PDU
preceding the handling of radio event done.

Symptoms of this bug being data transmission latency of upto
slave latency plus one times connection interval.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2020-05-22 16:47:57 +03:00
Morten Priess
2fa7a7e977 Bluetooth: controller: Added support for vendor ticker nodes
With BT_CTLR_USER_TICKER_ID_RANGE it is possible for vendors to add a
number of ticker nodes for proprietary purposes. The feature depends on
BT_CTLR_USER_EXT.

Signed-off-by: Morten Priess <mtpr@oticon.com>
2020-05-18 13:05:17 +03:00
Johan Hedberg
dbfc2ebc6b Bluetooth: Fix NULL pointer dereference when bt_send() fails
The last parameter to hci_cmd_done() is expected to be a valid net_buf
since the function immediately tries to dereference it. Fix this by
passing the appropriate buffer reference to the function.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2020-05-06 11:56:34 +03:00
Trond Einar Snekvik
82083a90cc Bluetooth: Mesh: net_key_status only pull one key idx
Fixes bug where the config client's net_key_status handler would attempt
to pull two key indexes from a message which only holds one.

Fixes #24601.

Signed-off-by: Trond Einar Snekvik <Trond.Einar.Snekvik@nordicsemi.no>
2020-04-28 21:31:18 +03:00
Gerson Fernando Budke
341681f312 lib: updatehub: Improve probe security
Improve buffer overflow security on probe_cb. This ensures that socket
buffer have fixed lenght and content received by COAP fills properly on
metadata buffer. After that, ensures that metadata content is a valid
string with length lower than metadata size.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
2020-04-22 14:37:28 +03:00
Gerson Fernando Budke
3f4221db6f lib: updatehub: Refact to use bin2hex
Use bin2hex instead inline conversion.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
2020-04-22 14:37:28 +03:00
Gerson Fernando Budke
4d949eebef lib: updatehub: Fix variable-size string copy
A malformed JSON payload that is received from an UpdateHub server
may trigger memory corruption in the Zephyr OS. This could result
in a denial of service in the best case, or code execution in the
worst case.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
2020-04-22 14:37:28 +03:00
Otavio Salvador
8e8ba2396c CODEOWNERS: Update UpdateHub owners
This replaces @chtavares592 with @nandojve as he will contributing to it
from now on.

Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
(cherry picked from commit a3d6b627b7)
2020-04-22 14:37:28 +03:00
Gerson Fernando Budke
0e51f8bd79 lib: updatehub: Add missing do upgrade request call
After a success image download, UpdateHub needs inform MCUboot that
must test new image and then, on success, commit this new image. This
add missing upgrade request call step and fixes the upgarde flow.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
(cherry picked from commit d1e2d345fb)
2020-04-22 14:37:28 +03:00
Gerson Fernando Budke
3e91120f2b lib: updatehub: Fix download block error
The current version aborts update when found last transfer block. Now,
system checks only at end of coap block transfer total size and install
if download is ok.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
(cherry picked from commit 1128eab3f2)
2020-04-22 14:37:28 +03:00
Gerson Fernando Budke
fb244f7542 lib: updatehub: Extract sha256 final method
Extract finish sha256 calc method.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
(cherry picked from commit 1fe1b0eec6)
2020-04-22 14:37:28 +03:00
Gerson Fernando Budke
f7ac49efe6 lib: updatehub: Fix buffer sizes
The MAX_PAYLOAD_SIZE must reflect the size of COAP_BLOCK_x. This is
necessary becase BLOCK size represents max payload size. The current
value create inconsistencies for coap lib. The same way,
MAX_DOWNLOAD_DATA must allocate sufficient space for MAX_PAYLOAD_SIZE
plus all space for coap header etc.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
(cherry picked from commit 5f5919a900)
2020-04-22 14:37:28 +03:00
Gerson Fernando Budke
fce4c9e317 lib: updatehub: Fix build warnings
Fix all build warnings.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
(cherry picked from commit 92f9cd9f85)
2020-04-22 14:37:28 +03:00
Flavio Ceolin
385f88242e net: coap: Fix possible overflow
Fix possible integer overflow when parsing a CoAP packet.

Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
2020-04-22 13:02:46 +03:00
Flavio Ceolin
4e8e72bd4c math: extras: Add overflow functions to u16
Add functions to addition and multiplication for u16_t.

Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
2020-04-22 13:02:46 +03:00
Vinayak Kariappa Chettimada
eee10e9aff Bluetooth: controller: split: Fix DLE duplicate requests
Fix implementation to handle back-to-back and duplicate
LENGTH_REQ PDU reception.

Relates to #23707.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2020-04-22 13:00:50 +03:00
Vinayak Kariappa Chettimada
b7e7153b95 Bluetooth: controller: split: Simplify DLE state checks
Simplify the Data Length Update Procedure state check when
processing incoming LENGTH_REQ/RSP PDUs.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2020-04-22 13:00:50 +03:00
Vinayak Kariappa Chettimada
525500123a Bluetooth: controller: split: Validate chan map and hop value
Add validation of channel map and hop increment value
received in CONNECT_IND PDU.

Zero bit count leads to controller assert or divide-by-zero
fault.

Hop increment shall be between 5 and 16 by BT Specification.

Relates to #23705.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2020-04-22 13:00:29 +03:00
Vinayak Kariappa Chettimada
ff39065ed4 Bluetooth: controller: Fix ticker ticks_current value
Update the ticks_current value on last stopped ticker
instance, so that when a new ticker instance is started
the anchor ticks calculation uses the correct current tick
with respect to supplied anchor ticks.

Fixes #23805.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2020-04-22 13:00:03 +03:00
Vinayak Kariappa Chettimada
1b253c2dba Bluetooth: controller: split: Fix slave latency during conn update
Fix regression in cancelling slave latency during Connection
Update Procedure.

Slave latency should not be applied between the ack of a
Connection Update Indication PDU and until the instant.
When caching was introduced, implementation missed this
consideration.

Relates to #23813.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2020-04-22 12:59:43 +03:00
Vinayak Kariappa Chettimada
37c46e3cf5 Bluetooth: controller: split: Fix regression in handling invalid pkt seq
Fix regression in handling invalid packet sequence in the
first packet in a connection.

This relates to commit 62c1e1a52b ("Bluetooth: controller:
split: Fix assert on invalid packet sequence")

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2020-04-22 12:59:20 +03:00
Andries Kruithof
c5f9a2d2bc [Backport-v2.2-branch] Bluetooth: controller: legacy: DLE timing
Fixes #23482.

There is a bug in calculation of time for the DLE procedure:
the preamble size is incorrect for the 2M phy

This is for the legacy code, see PR #23570 for the split controller

Signed-off-by: Andries Kruithof <Andries.Kruithof@nordicsemi.no>
2020-04-22 12:58:52 +03:00
Joakim Andersson
7e4bcff791 Bluetooth: SMP: Fix bond lost on pairing failure.
Fix an an issue where established bonding information in the peripheral
are deleted when the central does not have the bond information.
This could be because the central has removed the bond information, or
this is in fact not the central but someone spoofing it's identity, or
an accidental RPA match.

This is a regression from: a3e89e84a8

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
2020-04-22 12:58:19 +03:00
Vinayak Kariappa Chettimada
ee4006e42e Bluetooth: controller: nRF: Revert use of ticker compat mode as default
Ticker is now fixed to avoid catch up of periodic timeout under
large ISR latencies.

Revert commit a749e28d98 ("Bluetooth: controller: split:
nRF: Use ticker compat mode as default").

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2020-04-20 21:46:38 +03:00
Vinayak Kariappa Chettimada
bec2a497b9 Bluetooth: controller: Consider must_expire while avoiding catchup
If must_expire is set for a ticker instance, then ticker
expiry shall still perform catchup.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2020-04-20 21:46:38 +03:00
Vinayak Kariappa Chettimada
2295af0f05 Bluetooth: controller: Fix ticks_slot_previous calculation
Fix ticks_slot_previous calculation in the ticker_job when
tickers are skipped.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2020-04-20 21:46:38 +03:00
Vinayak Kariappa Chettimada
8e12b42af2 Bluetooth: controller: Fix ticker state on skipped
Reset ticker state in ticker_job for ticker instances that
have been skipped in the ticker_worker.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2020-04-20 21:46:38 +03:00
Vinayak Kariappa Chettimada
a3c2a72c6c Bluetooth: controller: Remove lazy handling in ticker_worker
Removed lazy handling from ticker_worker as it is now taken
care in ticker_job.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2020-04-20 21:46:38 +03:00
Vinayak Kariappa Chettimada
c2e829ba8c Bluetooth: controller: Fix ticker catch up on ISR latency
Fix ticker to avoid catch up of periodic timeouts in case of
large ISR latencies like in case of flash erase scenarios.

Relates to #23815.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2020-04-20 21:46:38 +03:00
Andries Kruithof
b83d9a5eea Bluetooth: controller: split: correct timing calculation in PKT_US
A bug in the PKT_US resulted in wrong calculations for the 2M phy.
Fixes the bug, verified on EBQ.
Also adds some defines for improved readability.

Fixes #23482

Signed-off-by: Andries Kruithof <Andries.Kruithof@nordicsemi.no>
2020-04-12 11:54:29 +03:00
Carles Cufi
a69cdb31ca ci: do not use latest sphinx/breathe releases for docs
Sphinx version 3.0.0 release recently break doc build, lock version
of sphinx to something compatible while we upgrade dependencies...

breathe v4.15.0 was just released and fixes some compatibility issues
with latest sphinx, the combo works, however with many warnings that we
still need to either fix or whitelist. This is temporary until we are
able to use those new versions.

Backport of #24109 and #24166

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
2020-04-08 17:14:25 +02:00
Dan Erichsen
d39cb42d09 bluetooth: host: Do not send unwanted SC indicate
Fixes #23485

When we create a GATT table dynamically, we also create a hash
identifying this table. This hash can be stored in persistent memory and
we can thus determine after recreating the GATT table whether the
services have changed or not from before the reboot.

When these hashes are identical, it implies that the table has not
changed, wherefore a service changed indication should not be sent to
any bonded clients. The method for achieving this was to remove the
gatt_sc.work entry from the work queue. This work queue entry was to
send an indication to the clients when the table had been allocated.
If the final entry then caused the hashes to match, the indication
would be cancelled.

On unit testing this behaviour in simulation and in practice, we found
that the indication was sent nonetheless, and the issue was located to
be tied to the SERVICE_RANGE_CHANGED flag which is set when the services
are changed and is cleared when the indications are being sent out.

It was the job of the work queue entry to clear this flag, and as the
entry was never serviced, the flag was never cleared, and when
sc_commit() is called at the end of the process, it believes that there
is a new service change pending and therefore starts the job over, thus
creating a redundant indication to the clients.

This commit fixes the issue by clearing the flag when the work entry
is removed due to a hash match. This has been unittested in a live
environment, in a simulation environment, and sanitycheck has been run
on it.

Signed-off-by: Dan Erichsen <daee@demant.com>
2020-03-17 18:16:57 +01:00
Wolfgang Puffitsch
9d83a7cd27 Bluetooth: controller: split: Fix response to unexpected LL_FEATURE_RSP
Fix response to unexpected LL_FEATURE_RSP for the case that
BT_CTLR_SLAVE_FEAT_REQ is disabled. Fixes LL/PAC/SLA/BV-01 for such a
configuration.

Signed-off-by: Wolfgang Puffitsch <wopu@demant.com>
2020-03-17 18:16:47 +01:00
31 changed files with 535 additions and 255 deletions

View File

@@ -30,8 +30,8 @@ jobs:
- name: install-pip
run: |
pip3 install setuptools
pip3 install 'breathe>=4.9.1' 'docutils>=0.14' \
'sphinx>=1.7.5' sphinx_rtd_theme sphinx-tabs \
pip3 install 'breathe>=4.9.1,<4.15.0' 'docutils>=0.14' \
'sphinx>=1.7.5,<3.0' sphinx_rtd_theme sphinx-tabs \
sphinxcontrib-svg2pdfconverter 'west>=0.6.2'
pip3 install pyelftools

View File

@@ -61,8 +61,8 @@ jobs:
- name: install-pip
run: |
pip3 install setuptools
pip3 install 'breathe>=4.9.1' 'docutils>=0.14' \
'sphinx>=1.7.5' sphinx_rtd_theme sphinx-tabs \
pip3 install 'breathe>=4.9.1,<4.15.0' 'docutils>=0.14' \
'sphinx>=1.7.5,<3.0' sphinx_rtd_theme sphinx-tabs \
sphinxcontrib-svg2pdfconverter 'west>=0.6.2'
pip3 install pyelftools

View File

@@ -347,7 +347,7 @@
/samples/ @nashif
/samples/basic/minimal/ @carlescufi
/samples/basic/servo_motor/*microbit* @jhe
/lib/updatehub/ @chtavares592 @otavio
/lib/updatehub/ @nandojve @otavio
/samples/bluetooth/ @jhedberg @Vudentz @joerchan
/samples/boards/intel_s1000_crb/ @sathishkuttan @dcpleung @nashif
/samples/display/ @vanwinkeljan
@@ -361,7 +361,7 @@
/samples/net/mqtt_publisher/ @jukkar @tbursztyka
/samples/net/sockets/coap_*/ @rveerama1
/samples/net/sockets/ @jukkar @tbursztyka @pfalcon
/samples/net/updatehub/ @chtavares592 @otavio
/samples/net/updatehub/ @nandojve @otavio
/samples/sensor/ @MaureenHelm
/samples/shields/ @avisconti
/samples/subsys/logging/ @nordic-krch @jakub-uC

View File

@@ -1,5 +1,5 @@
VERSION_MAJOR = 2
VERSION_MINOR = 2
PATCHLEVEL = 0
PATCHLEVEL = 1
VERSION_TWEAK = 0
EXTRAVERSION =

View File

@@ -1,6 +1,51 @@
:orphan:
.. _zephyr_2.2:
.. _zephyr_2.2.1:
Zephyr 2.2.1
#############
This is a maintenance release for Zephyr 2.2 with fixes.
See :ref:`zephyr_2.2.0` for the previous version release notes.
Security Vulnerability Related
******************************
The following security vulnerabilities (CVE) were addressed in this release:
* Fix CVE-2020-10028
* Fix CVE-2020-10060
* Fix CVE-2020-10063
* Fix CVE-2020-10066
More detailed information can be found in:
https://docs.zephyrproject.org/latest/security/vulnerabilities.html
Issues Fixed
************
These GitHub issues were addressed since the previous 2.2.0 tagged
release:
* :github:`23494` - Bluetooth: LL/PAC/SLA/BV-01-C fails if Slave-initiated Feature Exchange is disabled
* :github:`23485` - BT: host: Service Change indication sent regardless of whether it is needed or not.
* :github:`23482` - 2M PHY + DLE and timing calculations on an encrypted link are wrong
* :github:`23070` - Bluetooth: controller: Fix ticker implementation to avoid catch up
* :github:`22967` - Bluetooth: controller: ASSERTION FAIL on invalid packet sequence
* :github:`24183` - [v2.2] Bluetooth: controller: split: Regression slave latency during connection update
* :github:`23805` - Bluetooth: controller: Switching to non conn adv fails for Mesh LPN
* :github:`24086` - Bluetooth: SMP: Existing bond deleted on pairing failure
* :github:`24211` - [v2.2.x] lib: updatehub: Not working on Zephyr 2.x
* :github:`24601` - Bluetooth: Mesh: Config Client's net_key_status pulls two key indexes, should pull one.
* :github:`25067` - Insufficient ticker nodes for vendor implementations
* :github:`25350` - Bluetooth: controller: Data transmission delayed by slave latency
* :github:`25483` - Bluetooth: controller: split: feature exchange not conform V5.0 core spec
* :github:`25478` - settings_runtime_set() not populating bt/cf
* :github:`25447` - cf_set() returns 0 when no cfg is available
.. _zephyr_2.2.0:
Zephyr 2.2.0
############

View File

@@ -28,6 +28,7 @@
* true if the operation overflowed.
*/
/**@{*/
static bool u16_add_overflow(u16_t a, u16_t b, u16_t *result);
static bool u32_add_overflow(u32_t a, u32_t b, u32_t *result);
static bool u64_add_overflow(u64_t a, u64_t b, u64_t *result);
static bool size_add_overflow(size_t a, size_t b, size_t *result);
@@ -40,6 +41,7 @@ static bool size_add_overflow(size_t a, size_t b, size_t *result);
* true if the operation overflowed.
*/
/**@{*/
static bool u16_mul_overflow(u16_t a, u16_t b, u16_t *result);
static bool u32_mul_overflow(u32_t a, u32_t b, u32_t *result);
static bool u64_mul_overflow(u64_t a, u64_t b, u64_t *result);
static bool size_mul_overflow(size_t a, size_t b, size_t *result);

View File

@@ -29,6 +29,11 @@
#endif
#if use_builtin(__builtin_add_overflow)
static inline bool u16_add_overflow(u16_t a, u16_t b, u16_t *result)
{
return __builtin_add_overflow(a, b, result);
}
static inline bool u32_add_overflow(u32_t a, u32_t b, u32_t *result)
{
return __builtin_add_overflow(a, b, result);
@@ -44,6 +49,15 @@ static inline bool size_add_overflow(size_t a, size_t b, size_t *result)
return __builtin_add_overflow(a, b, result);
}
#else /* !use_builtin(__builtin_add_overflow) */
static inline bool u16_add_overflow(u16_t a, u16_t b, u16_t *result)
{
u16_t c = a + b;
*result = c;
return c < a;
}
static inline bool u32_add_overflow(u32_t a, u32_t b, u32_t *result)
{
u32_t c = a + b;
@@ -73,6 +87,11 @@ static inline bool size_add_overflow(size_t a, size_t b, size_t *result)
#endif /* use_builtin(__builtin_add_overflow) */
#if use_builtin(__builtin_mul_overflow)
static inline bool u16_mul_overflow(u16_t a, u16_t b, u16_t *result)
{
return __builtin_mul_overflow(a, b, result);
}
static inline bool u32_mul_overflow(u32_t a, u32_t b, u32_t *result)
{
return __builtin_mul_overflow(a, b, result);
@@ -88,6 +107,15 @@ static inline bool size_mul_overflow(size_t a, size_t b, size_t *result)
return __builtin_mul_overflow(a, b, result);
}
#else /* !use_builtin(__builtin_mul_overflow) */
static inline bool u16_mul_overflow(u16_t a, u16_t b, u16_t *result)
{
u16_t c = a * b;
*result = c;
return a != 0 && (c / a) != b;
}
static inline bool u32_mul_overflow(u32_t a, u32_t b, u32_t *result)
{
u32_t c = a * b;

View File

@@ -55,11 +55,11 @@ static int cmd_info(const struct shell *shell, size_t argc, char **argv)
ARG_UNUSED(argc);
ARG_UNUSED(argv);
char *device_id = k_malloc(DEVICE_ID_MAX_SIZE);
char *device_id = k_malloc(DEVICE_ID_HEX_MAX_SIZE);
char *firmware_version = k_malloc(BOOT_IMG_VER_STRLEN_MAX);
updatehub_get_device_identity(device_id, DEVICE_ID_HEX_MAX_SIZE);
updatehub_get_firmware_version(firmware_version, BOOT_IMG_VER_STRLEN_MAX);
updatehub_get_device_identity(device_id, DEVICE_ID_MAX_SIZE);
shell_fprintf(shell, SHELL_NORMAL, "Unique device id: %s\n",
device_id);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2019 O.S.Systems
* Copyright (c) 2018-2020 O.S.Systems
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -35,11 +35,18 @@ LOG_MODULE_REGISTER(updatehub);
#define NETWORK_TIMEOUT K_SECONDS(2)
#define UPDATEHUB_POLL_INTERVAL K_MINUTES(CONFIG_UPDATEHUB_POLL_INTERVAL)
#define MAX_PATH_SIZE 255
#define MAX_PAYLOAD_SIZE 500
#define MAX_DOWNLOAD_DATA 1100
/* MAX_PAYLOAD_SIZE must reflect size COAP_BLOCK_x option */
#define MAX_PAYLOAD_SIZE 1024
/* MAX_DOWNLOAD_DATA must be equal or bigger than:
* MAX_PAYLOAD_SIZE + (len + header + options)
* otherwise download size will be less than real size.
*/
#define MAX_DOWNLOAD_DATA (MAX_PAYLOAD_SIZE + 32)
#define COAP_MAX_RETRY 3
#define MAX_IP_SIZE 30
#define SHA256_HEX_DIGEST_SIZE ((TC_SHA256_DIGEST_SIZE * 2) + 1)
#if defined(CONFIG_UPDATEHUB_CE)
#define UPDATEHUB_SERVER CONFIG_UPDATEHUB_SERVER
#else
@@ -61,11 +68,31 @@ static struct updatehub_context {
} ctx;
static struct update_info {
char package_uid[TC_SHA256_BLOCK_SIZE + 1];
char sha256sum_image[TC_SHA256_BLOCK_SIZE + 1];
char package_uid[SHA256_HEX_DIGEST_SIZE];
char sha256sum_image[SHA256_HEX_DIGEST_SIZE];
int image_size;
} update_info;
static struct k_delayed_work updatehub_work_handle;
static int bin2hex_str(u8_t *bin, size_t bin_len, char *str, size_t str_buf_len)
{
if (bin == NULL || str == NULL) {
return -1;
}
/* ensures at least an empty string */
if (str_buf_len < 1) {
return -2;
}
memset(str, 0, str_buf_len);
/* str_buf_len - 1 ensure space for \0 */
bin2hex(bin, bin_len, str, str_buf_len - 1);
return 0;
}
static void wait_fds(void)
{
if (poll(ctx.fds, ctx.nfds, NETWORK_TIMEOUT) < 0) {
@@ -76,7 +103,7 @@ static void wait_fds(void)
static void prepare_fds(void)
{
ctx.fds[ctx.nfds].fd = ctx.sock;
ctx.fds[ctx.nfds].events = 1;
ctx.fds[ctx.nfds].events = POLLIN;
ctx.nfds++;
}
@@ -84,8 +111,6 @@ static int metadata_hash_get(char *metadata)
{
struct tc_sha256_state_struct sha256sum;
unsigned char hash[TC_SHA256_DIGEST_SIZE];
char buffer[3];
int buffer_len = 0;
if (tc_sha256_init(&sha256sum) == 0) {
return -1;
@@ -99,13 +124,9 @@ static int metadata_hash_get(char *metadata)
return -1;
}
memset(update_info.package_uid, 0, TC_SHA256_BLOCK_SIZE + 1);
for (int i = 0; i < TC_SHA256_DIGEST_SIZE; i++) {
snprintk(buffer, sizeof(buffer), "%02x",
hash[i]);
buffer_len = buffer_len + strlen(buffer);
strncat(&update_info.package_uid[i], buffer,
MIN(TC_SHA256_BLOCK_SIZE, buffer_len));
if (bin2hex_str(hash, TC_SHA256_DIGEST_SIZE,
update_info.package_uid, SHA256_HEX_DIGEST_SIZE)) {
return -1;
}
return 0;
@@ -141,7 +162,7 @@ static bool start_coap_client(void)
}
#if defined(CONFIG_UPDATEHUB_DTLS)
int verify = TLS_PEER_VERIFY_NONE;
int verify = TLS_PEER_VERIFY_REQUIRED;
sec_tag_t sec_list[] = { CA_CERTIFICATE_TAG };
int protocol = IPPROTO_DTLS_1_2;
char port[] = "5684";
@@ -288,7 +309,7 @@ static int send_request(enum coap_msgtype msgtype, enum coap_method method,
}
ret = coap_packet_append_payload(&request_packet,
&ctx.payload,
ctx.payload,
strlen(ctx.payload));
if (ret < 0) {
LOG_ERR("Not able to append payload");
@@ -315,12 +336,36 @@ error:
return ret;
}
static bool install_update_cb_sha256(void)
{
u8_t hash[TC_SHA256_DIGEST_SIZE];
char sha256[SHA256_HEX_DIGEST_SIZE];
if (tc_sha256_final(hash, &ctx.sha256sum) < 1) {
LOG_ERR("Could not finish sha256sum");
return false;
}
if (bin2hex_str(hash, TC_SHA256_DIGEST_SIZE,
sha256, SHA256_HEX_DIGEST_SIZE)) {
LOG_ERR("Could not create sha256sum hex representation");
return false;
}
if (strncmp(sha256, update_info.sha256sum_image,
SHA256_HEX_DIGEST_SIZE) != 0) {
LOG_ERR("SHA256SUM of image are not the same");
ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR;
return false;
}
return true;
}
static void install_update_cb(void)
{
struct coap_packet response_packet;
char buffer[3], sha256_image_dowloaded[TC_SHA256_BLOCK_SIZE + 1];
u8_t *data = k_malloc(MAX_DOWNLOAD_DATA);
int i, buffer_len = 0;
int rcvd = -1;
if (data == NULL) {
@@ -370,32 +415,15 @@ static void install_update_cb(void)
}
if (coap_next_block(&response_packet, &ctx.block) == 0) {
LOG_ERR("Could not get the next");
ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR;
goto cleanup;
}
if (ctx.downloaded_size == ctx.block.total_size) {
u8_t image_hash[TC_SHA256_DIGEST_SIZE];
if (tc_sha256_final(image_hash, &ctx.sha256sum) < 1) {
LOG_ERR("Could not finish sha256sum");
if (ctx.downloaded_size != ctx.block.total_size) {
LOG_ERR("Could not get the next coap block");
ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR;
goto cleanup;
}
memset(&sha256_image_dowloaded, 0, TC_SHA256_BLOCK_SIZE + 1);
for (i = 0; i < TC_SHA256_DIGEST_SIZE; i++) {
snprintk(buffer, sizeof(buffer), "%02x", image_hash[i]);
buffer_len = buffer_len + strlen(buffer);
strncat(&sha256_image_dowloaded[i], buffer,
MIN(TC_SHA256_BLOCK_SIZE, buffer_len));
}
if (strncmp(sha256_image_dowloaded,
update_info.sha256sum_image,
strlen(update_info.sha256sum_image)) != 0) {
LOG_ERR("SHA256SUM of image are not the same");
LOG_INF("Firmware downloaded successfully");
if (!install_update_cb_sha256()) {
LOG_ERR("Firmware validation has failed");
ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR;
goto cleanup;
}
@@ -479,7 +507,7 @@ static int report(enum updatehub_state state)
struct report report;
int ret = -1;
const char *exec = state_name(state);
char *device_id = k_malloc(DEVICE_ID_MAX_SIZE);
char *device_id = k_malloc(DEVICE_ID_HEX_MAX_SIZE);
char *firmware_version = k_malloc(BOOT_IMG_VER_STRLEN_MAX);
if (device_id == NULL || firmware_version == NULL) {
@@ -487,7 +515,7 @@ static int report(enum updatehub_state state)
goto error;
}
if (!updatehub_get_device_identity(device_id, DEVICE_ID_MAX_SIZE)) {
if (!updatehub_get_device_identity(device_id, DEVICE_ID_HEX_MAX_SIZE)) {
goto error;
}
@@ -559,22 +587,23 @@ error:
return ret;
}
static void probe_cb(char *metadata)
static void probe_cb(char *metadata, size_t metadata_size)
{
struct coap_packet reply;
char tmp[MAX_PAYLOAD_SIZE];
char tmp[MAX_DOWNLOAD_DATA];
size_t tmp_len;
int rcvd = -1;
wait_fds();
rcvd = recv(ctx.sock, metadata, MAX_PAYLOAD_SIZE, MSG_DONTWAIT);
rcvd = recv(ctx.sock, tmp, MAX_DOWNLOAD_DATA, MSG_DONTWAIT);
if (rcvd <= 0) {
LOG_ERR("Could not receive data");
ctx.code_status = UPDATEHUB_NETWORKING_ERROR;
return;
}
if (coap_packet_parse(&reply, metadata, rcvd, NULL, 0) < 0) {
if (coap_packet_parse(&reply, tmp, rcvd, NULL, 0) < 0) {
LOG_ERR("Invalid data received");
ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR;
return;
@@ -586,10 +615,25 @@ static void probe_cb(char *metadata)
return;
}
memset(&tmp, 0, MAX_PAYLOAD_SIZE);
memcpy(tmp, reply.data + reply.offset, reply.max_len - reply.offset);
memset(metadata, 0, MAX_PAYLOAD_SIZE);
memcpy(metadata, tmp, strlen(tmp));
/* check if we have buffer space to receive payload */
if (metadata_size < (reply.max_len - reply.offset)) {
LOG_ERR("There is no buffer available");
ctx.code_status = UPDATEHUB_METADATA_ERROR;
return;
}
memcpy(metadata, reply.data + reply.offset,
reply.max_len - reply.offset);
/* ensures payload have a valid string with size lower
* than metadata_size
*/
tmp_len = strlen(metadata);
if (tmp_len >= metadata_size) {
LOG_ERR("Invalid metadata data received");
ctx.code_status = UPDATEHUB_METADATA_ERROR;
return;
}
ctx.code_status = UPDATEHUB_OK;
@@ -602,11 +646,13 @@ enum updatehub_response updatehub_probe(void)
struct resp_probe_some_boards metadata_some_boards;
struct resp_probe_any_boards metadata_any_boards;
char *metadata = k_malloc(MAX_PAYLOAD_SIZE);
char *metadata_copy = k_malloc(MAX_PAYLOAD_SIZE);
char *device_id = k_malloc(DEVICE_ID_MAX_SIZE);
char *metadata = k_malloc(MAX_DOWNLOAD_DATA);
char *metadata_copy = k_malloc(MAX_DOWNLOAD_DATA);
char *device_id = k_malloc(DEVICE_ID_HEX_MAX_SIZE);
char *firmware_version = k_malloc(BOOT_IMG_VER_STRLEN_MAX);
size_t sha256size;
if (device_id == NULL || firmware_version == NULL ||
metadata == NULL || metadata_copy == NULL) {
LOG_ERR("Could not alloc probe memory");
@@ -614,8 +660,6 @@ enum updatehub_response updatehub_probe(void)
goto error;
}
k_sem_init(&ctx.semaphore, 0, 1);
if (!boot_is_img_confirmed()) {
LOG_ERR("The current image is not confirmed");
ctx.code_status = UPDATEHUB_UNCONFIRMED_IMAGE;
@@ -627,7 +671,7 @@ enum updatehub_response updatehub_probe(void)
goto error;
}
if (!updatehub_get_device_identity(device_id, DEVICE_ID_MAX_SIZE)) {
if (!updatehub_get_device_identity(device_id, DEVICE_ID_HEX_MAX_SIZE)) {
ctx.code_status = UPDATEHUB_METADATA_ERROR;
goto error;
}
@@ -658,8 +702,7 @@ enum updatehub_response updatehub_probe(void)
goto cleanup;
}
memset(metadata, 0, MAX_PAYLOAD_SIZE);
probe_cb(metadata);
probe_cb(metadata, MAX_DOWNLOAD_DATA);
if (ctx.code_status != UPDATEHUB_OK) {
goto cleanup;
@@ -687,9 +730,18 @@ enum updatehub_response updatehub_probe(void)
goto cleanup;
}
sha256size = strlen(
metadata_any_boards.objects[1].objects.sha256sum) + 1;
if (sha256size != SHA256_HEX_DIGEST_SIZE) {
LOG_ERR("SHA256 size is invalid");
ctx.code_status = UPDATEHUB_METADATA_ERROR;
goto cleanup;
}
memcpy(update_info.sha256sum_image,
metadata_any_boards.objects[1].objects.sha256sum,
strlen(metadata_any_boards.objects[1].objects.sha256sum));
SHA256_HEX_DIGEST_SIZE);
update_info.image_size = metadata_any_boards.objects[1].objects.size;
} else {
if (!is_compatible_hardware(&metadata_some_boards)) {
@@ -698,10 +750,19 @@ enum updatehub_response updatehub_probe(void)
UPDATEHUB_INCOMPATIBLE_HARDWARE;
goto cleanup;
}
sha256size = strlen(
metadata_any_boards.objects[1].objects.sha256sum) + 1;
if (sha256size != SHA256_HEX_DIGEST_SIZE) {
LOG_ERR("SHA256 size is invalid");
ctx.code_status = UPDATEHUB_METADATA_ERROR;
goto cleanup;
}
memcpy(update_info.sha256sum_image,
metadata_some_boards.objects[1].objects.sha256sum,
strlen(metadata_some_boards.objects[1]
.objects.sha256sum));
SHA256_HEX_DIGEST_SIZE);
update_info.image_size =
metadata_some_boards.objects[1].objects.size;
}
@@ -741,6 +802,12 @@ enum updatehub_response updatehub_update(void)
goto error;
}
if (boot_request_upgrade(BOOT_UPGRADE_TEST)) {
LOG_ERR("Could not reporting downloaded state");
ctx.code_status = UPDATEHUB_INSTALL_ERROR;
goto error;
}
if (report(UPDATEHUB_STATE_INSTALLED) < 0) {
LOG_ERR("Could not reporting installed state");
goto error;
@@ -765,7 +832,7 @@ error:
return ctx.code_status;
}
static void autohandler(struct k_delayed_work *work)
static void autohandler(struct k_work *work)
{
switch (updatehub_probe()) {
case UPDATEHUB_UNCONFIRMED_IMAGE:
@@ -794,13 +861,11 @@ static void autohandler(struct k_delayed_work *work)
break;
}
k_delayed_work_submit(work, UPDATEHUB_POLL_INTERVAL);
k_delayed_work_submit(&updatehub_work_handle, UPDATEHUB_POLL_INTERVAL);
}
void updatehub_autohandler(void)
{
static struct k_delayed_work work;
k_delayed_work_init(&work, autohandler);
k_delayed_work_submit(&work, K_NO_WAIT);
k_delayed_work_init(&updatehub_work_handle, autohandler);
k_delayed_work_submit(&updatehub_work_handle, K_NO_WAIT);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 O.S.Systems
* Copyright (c) 2018-2020 O.S.Systems
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -7,23 +7,16 @@
bool updatehub_get_device_identity(char *id, int id_max_len)
{
int i, id_len = 0, buf_len = 0;
char buf[3];
u8_t hwinfo_id[id_max_len];
u8_t hwinfo_id[DEVICE_ID_BIN_MAX_SIZE];
size_t length;
length = hwinfo_get_device_id(hwinfo_id, sizeof(hwinfo_id) - 1);
length = hwinfo_get_device_id(hwinfo_id, DEVICE_ID_BIN_MAX_SIZE);
if (length <= 0) {
return false;
}
memset(id, 0, id_max_len);
length = bin2hex(hwinfo_id, length, id, id_max_len - 1);
for (i = 0; i < length; i++) {
snprintk(buf, sizeof(buf), "%02x", hwinfo_id[i]);
id_len = strlen(id);
strncat(id, buf, id_max_len - id_len);
}
return true;
return length > 0;
}

View File

@@ -10,7 +10,8 @@
#include <zephyr.h>
#include <drivers/hwinfo.h>
#define DEVICE_ID_MAX_SIZE 65
#define DEVICE_ID_BIN_MAX_SIZE 64
#define DEVICE_ID_HEX_MAX_SIZE ((DEVICE_ID_BIN_MAX_SIZE * 2) + 1)
bool updatehub_get_device_identity(char *id, int id_max_len);

View File

@@ -2,7 +2,7 @@
CONFIG_UPDATEHUB=y
#Minimal Heap mem pool size for the updatehub working
CONFIG_HEAP_MEM_POOL_SIZE=2048
CONFIG_HEAP_MEM_POOL_SIZE=8192
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
CONFIG_NET_IPV4=y

View File

@@ -1,7 +1,7 @@
Pillow
PyYAML>=5.1
anytree
breathe>=4.9.1
breathe>=4.9.1,<4.15.0
colorama
docutils>=0.14
gcovr>=4.2
@@ -15,7 +15,7 @@ pykwalify
pyocd>=0.24.0
pyserial
pytest
sphinx>=1.7.5
sphinx>=1.7.5,<3.0.0
sphinx_rtd_theme
sphinx-tabs
sphinxcontrib-svg2pdfconverter

View File

@@ -117,7 +117,6 @@ config BT_LLL_VENDOR_NORDIC
select BT_HAS_HCI_VS
select ENTROPY_NRF5_RNG
select ENTROPY_NRF5_BIAS_CORRECTION
select BT_CTLR_LE_ENC_SUPPORT if !BT_CTLR_DATA_LENGTH_CLEAR && \
!BT_CTLR_PHY_2M_NRF
select BT_CTLR_CONN_PARAM_REQ_SUPPORT
@@ -137,11 +136,6 @@ config BT_LLL_VENDOR_NORDIC
select BT_CTLR_XTAL_ADVANCED_SUPPORT
select BT_CTLR_SCHED_ADVANCED_SUPPORT
select BT_CTLR_TIFS_HW_SUPPORT
# Until ticker resolve collision is fixed for skipped ticker catch-up
# issue, use the old compatibility mode
select BT_TICKER_COMPATIBILITY_MODE
default y
help
Use Nordic Lower Link Layer implementation.
@@ -876,6 +870,15 @@ config BT_CTLR_USER_EVT_RANGE
Number of event types reserved for proprietary use. The range
is typically used when BT_CTLR_USER_EXT is in use.
config BT_CTLR_USER_TICKER_ID_RANGE
int "Range of ticker id constants reserved for proprietary ticker nodes"
depends on BT_CTLR_USER_EXT
default 0
range 0 10
help
Number of ticker ids reserved for proprietary use. The range
is typically used when BT_CTLR_USER_EXT is in use.
config BT_RX_USER_PDU_LEN
int "Maximum supported proprietary PDU buffer length"
depends on BT_CTLR_USER_EXT

View File

@@ -103,6 +103,7 @@
#define LL_FEAT_BIT_MASK 0x1FFFF
#define LL_FEAT_BIT_MASK_VALID 0x1CF2F
#define LL_FEAT_FILTER_OCTET0 0x1FF00
#define LL_FEAT (LL_FEAT_BIT_ENC | \
LL_FEAT_BIT_CONN_PARAM_REQ | \
LL_FEAT_BIT_EXT_REJ_IND | \

View File

@@ -66,10 +66,11 @@
#define RADIO_PKT_TIME(octets, phy) \
(((phy) & BIT(2)) ? \
(80 + 256 + 16 + 24 + ((((2 + (octets) + 4) * 8) + 24 + 3) * 8)) : \
(((octets) + 14) * 8 / BIT(((phy) & 0x03) >> 1)))
(((octets) + 13 + PREAMBLE_SIZE(phy)) * 8 / \
BIT(((phy) & 0x03) >> 1)))
#else /* !CONFIG_BT_CTLR_PHY_CODED */
#define RADIO_PKT_TIME(octets, phy) \
(((octets) + 14) * 8 / BIT(((phy) & 0x03) >> 1))
(((octets) + 13 + PREAMBLE_SIZE(phy)) * 8 / BIT(((phy) & 0x03) >> 1))
#endif /* !CONFIG_BT_CTLR_PHY_CODED */
/* Inter Frame Space */
@@ -641,7 +642,8 @@ static void common_init(void)
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
/* Initialize the DLE defaults */
_radio.default_tx_octets = PDU_DC_PAYLOAD_SIZE_MIN;
_radio.default_tx_time = RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0);
_radio.default_tx_time =
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, BIT(0));
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
#if defined(CONFIG_BT_CTLR_PHY)
@@ -2245,8 +2247,8 @@ isr_rx_conn_pkt_ctrl_rej_dle(struct radio_pdu_node_rx *node_rx,
lr->max_rx_octets = conn->max_rx_octets;
lr->max_tx_octets = conn->max_tx_octets;
#if !defined(CONFIG_BT_CTLR_PHY)
lr->max_rx_time = RADIO_PKT_TIME(conn->max_rx_octets, 0);
lr->max_tx_time = RADIO_PKT_TIME(conn->max_tx_octets, 0);
lr->max_rx_time = RADIO_PKT_TIME(conn->max_rx_octets, BIT(0));
lr->max_tx_time = RADIO_PKT_TIME(conn->max_tx_octets, BIT(0));
#else /* CONFIG_BT_CTLR_PHY */
lr->max_rx_time = conn->max_rx_time;
lr->max_tx_time = conn->max_tx_time;
@@ -2464,7 +2466,7 @@ static inline u8_t isr_rx_conn_pkt_ctrl_dle(struct pdu_data *pdu_data_rx,
* peer max_rx_time
*/
if (lr->max_rx_time >=
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0)) {
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, BIT(0))) {
eff_tx_time =
MIN(lr->max_rx_time,
_radio.conn_curr->default_tx_time);
@@ -2480,7 +2482,7 @@ static inline u8_t isr_rx_conn_pkt_ctrl_dle(struct pdu_data *pdu_data_rx,
* peer max_tx_time
*/
if (lr->max_tx_time >=
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0)) {
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, BIT(0))) {
eff_rx_time =
MIN(lr->max_tx_time,
RADIO_PKT_TIME(LL_LENGTH_OCTETS_RX_MAX,
@@ -2610,8 +2612,8 @@ static inline u8_t isr_rx_conn_pkt_ctrl_dle(struct pdu_data *pdu_data_rx,
lr->max_tx_octets = eff_tx_octets;
#if !defined(CONFIG_BT_CTLR_PHY)
lr->max_rx_time = RADIO_PKT_TIME(eff_rx_octets, 0);
lr->max_tx_time = RADIO_PKT_TIME(eff_tx_octets, 0);
lr->max_rx_time = RADIO_PKT_TIME(eff_rx_octets, BIT(0));
lr->max_tx_time = RADIO_PKT_TIME(eff_tx_octets, BIT(0));
#else /* CONFIG_BT_CTLR_PHY */
lr->max_rx_time = eff_rx_time;
lr->max_tx_time = eff_tx_time;
@@ -4849,10 +4851,10 @@ static inline void isr_close_conn(void)
rx_time = conn->max_rx_time;
}
#else /* !CONFIG_BT_CTLR_DATA_LENGTH */
tx_time = MAX(RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0),
tx_time = MAX(RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, BIT(0)),
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN,
conn->phy_tx));
rx_time = MAX(RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0),
rx_time = MAX(RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, BIT(0)),
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN,
conn->phy_rx));
#endif /* !CONFIG_BT_CTLR_DATA_LENGTH */
@@ -4860,12 +4862,13 @@ static inline void isr_close_conn(void)
ready_delay = (conn->role) ?
radio_rx_ready_delay_get(0, 0) :
radio_tx_ready_delay_get(0, 0);
tx_time = RADIO_PKT_TIME(conn->max_tx_octets, 0);
tx_time = RADIO_PKT_TIME(conn->max_tx_octets, BIT(0));
if (conn->evt_len_adv) {
rx_time = RADIO_PKT_TIME(conn->llcp_length.rx_octets,
0);
BIT(0));
} else {
rx_time = RADIO_PKT_TIME(conn->max_rx_octets, 0);
rx_time = RADIO_PKT_TIME(conn->max_rx_octets,
BIT(0));
}
#endif /* !CONFIG_BT_CTLR_PHY */
@@ -8428,12 +8431,12 @@ static inline int event_len_prep(struct connection *conn)
#endif /* !CONFIG_BT_CTLR_PHY */
) {
lr->max_rx_time =
RADIO_PKT_TIME(LL_LENGTH_OCTETS_RX_MAX, 0);
RADIO_PKT_TIME(LL_LENGTH_OCTETS_RX_MAX, BIT(0));
#if defined(CONFIG_BT_CTLR_PHY)
lr->max_tx_time = conn->default_tx_time;
#else /* !CONFIG_BT_CTLR_PHY */
lr->max_tx_time =
RADIO_PKT_TIME(conn->default_tx_octets, 0);
RADIO_PKT_TIME(conn->default_tx_octets, BIT(0));
#endif /* !CONFIG_BT_CTLR_PHY */
#if defined(CONFIG_BT_CTLR_PHY)
@@ -8637,8 +8640,8 @@ static inline int event_len_prep(struct connection *conn)
lr->max_rx_octets = conn->max_rx_octets;
lr->max_tx_octets = tx_octets;
#if !defined(CONFIG_BT_CTLR_PHY)
lr->max_rx_time = RADIO_PKT_TIME(conn->max_rx_octets, 0);
lr->max_tx_time = RADIO_PKT_TIME(tx_octets, 0);
lr->max_rx_time = RADIO_PKT_TIME(conn->max_rx_octets, BIT(0));
lr->max_tx_time = RADIO_PKT_TIME(tx_octets, BIT(0));
#else /* CONFIG_BT_CTLR_PHY */
lr->max_rx_time = conn->max_rx_time;
lr->max_tx_time = tx_time;
@@ -8862,7 +8865,7 @@ static inline void event_phy_upd_ind_prep(struct connection *conn,
u16_t tx_time = RADIO_PKT_TIME(conn->max_tx_octets,
conn->phy_tx);
if (tx_time >=
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0)) {
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, BIT(0))) {
eff_tx_time = MIN(tx_time,
conn->default_tx_time);
#if defined(CONFIG_BT_CTLR_PHY_CODED)
@@ -8873,7 +8876,7 @@ static inline void event_phy_upd_ind_prep(struct connection *conn,
} else {
eff_tx_time =
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN,
0);
BIT(0));
}
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
}
@@ -8885,7 +8888,7 @@ static inline void event_phy_upd_ind_prep(struct connection *conn,
u16_t rx_time = RADIO_PKT_TIME(conn->max_rx_octets,
conn->phy_rx);
if (rx_time >=
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0)) {
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, BIT(0))) {
eff_rx_time = MIN(rx_time,
RADIO_PKT_TIME(LL_LENGTH_OCTETS_RX_MAX,
BIT(2)));
@@ -8897,7 +8900,7 @@ static inline void event_phy_upd_ind_prep(struct connection *conn,
} else {
eff_rx_time =
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN,
0);
BIT(0));
}
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
}
@@ -11043,9 +11046,9 @@ static void length_resp_send(struct connection *conn,
#if !defined(CONFIG_BT_CTLR_PHY)
pdu_ctrl_tx->llctrl.length_rsp.max_rx_time =
RADIO_PKT_TIME(eff_rx_octets, 0);
RADIO_PKT_TIME(eff_rx_octets, BIT(0));
pdu_ctrl_tx->llctrl.length_rsp.max_tx_time =
RADIO_PKT_TIME(eff_tx_octets, 0);
RADIO_PKT_TIME(eff_tx_octets, BIT(0));
#else /* CONFIG_BT_CTLR_PHY */
pdu_ctrl_tx->llctrl.length_rsp.max_rx_time = eff_rx_time;
pdu_ctrl_tx->llctrl.length_rsp.max_tx_time = eff_tx_time;
@@ -11536,9 +11539,9 @@ u32_t radio_adv_enable(u16_t interval, u8_t chan_map, u8_t filter_policy,
#if defined(CONFIG_BT_CTLR_PHY)
conn->default_tx_time = _radio.default_tx_time;
conn->max_tx_time =
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0);
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, BIT(0));
conn->max_rx_time =
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0);
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, BIT(0));
#endif /* CONFIG_BT_CTLR_PHY */
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
@@ -12075,8 +12078,8 @@ u32_t radio_connect_enable(u8_t adv_addr_type, u8_t *adv_addr, u16_t interval,
#if defined(CONFIG_BT_CTLR_PHY)
conn->default_tx_time = _radio.default_tx_time;
conn->max_tx_time = RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0);
conn->max_rx_time = RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0);
conn->max_tx_time = RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, BIT(0));
conn->max_rx_time = RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, BIT(0));
#endif /* CONFIG_BT_CTLR_PHY */
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */

View File

@@ -54,6 +54,13 @@ enum {
1),
#endif /* CONFIG_BT_CONN */
#if defined(CONFIG_BT_CTLR_USER_EXT) && \
(CONFIG_BT_CTLR_USER_TICKER_ID_RANGE > 0)
TICKER_ID_USER_BASE,
TICKER_ID_USER_LAST = (TICKER_ID_USER_BASE +
CONFIG_BT_CTLR_USER_TICKER_ID_RANGE - 1),
#endif /* CONFIG_BT_CTLR_USER_EXT */
TICKER_ID_MAX,
};

View File

@@ -688,6 +688,7 @@ static int isr_rx_pdu(struct lll_conn *lll, struct pdu_data *pdu_data_rx,
if (link) {
struct pdu_data *pdu_data_tx;
u8_t pdu_data_tx_len;
u8_t offset;
pdu_data_tx = (void *)(tx->pdu +
lll->packet_tx_head_offset);
@@ -702,9 +703,10 @@ static int isr_rx_pdu(struct lll_conn *lll, struct pdu_data *pdu_data_rx,
}
#endif /* CONFIG_BT_CTLR_LE_ENC */
lll->packet_tx_head_offset += pdu_data_tx_len;
if (lll->packet_tx_head_offset ==
lll->packet_tx_head_len) {
offset = lll->packet_tx_head_offset + pdu_data_tx_len;
if (offset < lll->packet_tx_head_len) {
lll->packet_tx_head_offset = offset;
} else if (offset == lll->packet_tx_head_len) {
lll->packet_tx_head_len = 0;
lll->packet_tx_head_offset = 0;

View File

@@ -98,11 +98,18 @@
#define FLASH_TICKER_USER_APP_OPS 0
#endif
#if defined(CONFIG_BT_CTLR_USER_EXT)
#define USER_TICKER_NODES CONFIG_BT_CTLR_USER_TICKER_ID_RANGE
#else
#define USER_TICKER_NODES 0
#endif
#define TICKER_NODES (TICKER_ID_ULL_BASE + \
BT_ADV_TICKER_NODES + \
BT_SCAN_TICKER_NODES + \
BT_CONN_TICKER_NODES + \
FLASH_TICKER_NODES)
FLASH_TICKER_NODES + \
USER_TICKER_NODES)
#define TICKER_USER_APP_OPS (TICKER_USER_THREAD_OPS + \
FLASH_TICKER_USER_APP_OPS)
#define TICKER_USER_OPS (TICKER_USER_LLL_OPS + \

View File

@@ -600,8 +600,8 @@ u8_t ll_adv_enable(u8_t enable)
/* Use the default 1M packet max time. Value of 0 is
* equivalent to using BIT(0).
*/
conn_lll->max_tx_time = PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, 0);
conn_lll->max_rx_time = PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, 0);
conn_lll->max_tx_time = PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M);
conn_lll->max_rx_time = PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M);
#endif /* CONFIG_BT_CTLR_PHY */
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
@@ -650,7 +650,8 @@ u8_t ll_adv_enable(u8_t enable)
conn->llcp_rx = NULL;
conn->llcp_cu.req = conn->llcp_cu.ack = 0;
conn->llcp_feature.req = conn->llcp_feature.ack = 0;
conn->llcp_feature.features = LL_FEAT;
conn->llcp_feature.features_conn = LL_FEAT;
conn->llcp_feature.features_peer = 0;
conn->llcp_version.req = conn->llcp_version.ack = 0;
conn->llcp_version.tx = conn->llcp_version.rx = 0;
conn->llcp_terminate.reason_peer = 0;

View File

@@ -275,7 +275,7 @@ u8_t ll_conn_update(u16_t handle, u8_t cmd, u8_t status, u16_t interval_min,
#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
if (!conn->llcp_conn_param.disabled &&
(!conn->common.fex_valid ||
(conn->llcp_feature.features &
(conn->llcp_feature.features_conn &
BIT(BT_LE_FEAT_BIT_CONN_PARAM_REQ)))) {
cmd++;
} else if (conn->lll.role) {
@@ -480,12 +480,12 @@ void ll_length_max_get(u16_t *max_tx_octets, u16_t *max_tx_time,
*max_tx_octets = LL_LENGTH_OCTETS_RX_MAX;
*max_rx_octets = LL_LENGTH_OCTETS_RX_MAX;
#if defined(CONFIG_BT_CTLR_PHY)
*max_tx_time = PKT_US(LL_LENGTH_OCTETS_RX_MAX, BIT(2));
*max_rx_time = PKT_US(LL_LENGTH_OCTETS_RX_MAX, BIT(2));
*max_tx_time = PKT_US(LL_LENGTH_OCTETS_RX_MAX, PHY_CODED);
*max_rx_time = PKT_US(LL_LENGTH_OCTETS_RX_MAX, PHY_CODED);
#else /* !CONFIG_BT_CTLR_PHY */
/* Default is 1M packet timing */
*max_tx_time = PKT_US(LL_LENGTH_OCTETS_RX_MAX, 0);
*max_rx_time = PKT_US(LL_LENGTH_OCTETS_RX_MAX, 0);
*max_tx_time = PKT_US(LL_LENGTH_OCTETS_RX_MAX, PHY_1M);
*max_rx_time = PKT_US(LL_LENGTH_OCTETS_RX_MAX, PHY_1M);
#endif /* !CONFIG_BT_CTLR_PHY */
}
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
@@ -1045,6 +1045,10 @@ void ull_conn_done(struct node_rx_event_done *done)
ull_slave_done(done, &ticks_drift_plus,
&ticks_drift_minus);
if (!conn->tx_head) {
ull_conn_tx_demux(UINT8_MAX);
}
if (conn->tx_head || memq_peek(lll->memq_tx.head,
lll->memq_tx.tail,
NULL)) {
@@ -1209,9 +1213,10 @@ void ull_conn_done(struct node_rx_event_done *done)
#endif /* CONFIG_BT_CTLR_CONN_RSSI */
/* break latency based on ctrl procedure pending */
if ((((conn->llcp_req - conn->llcp_ack) & 0x03) == 0x02) &&
((conn->llcp_type == LLCP_CONN_UPD) ||
(conn->llcp_type == LLCP_CHAN_MAP))) {
if (((((conn->llcp_req - conn->llcp_ack) & 0x03) == 0x02) &&
((conn->llcp_type == LLCP_CONN_UPD) ||
(conn->llcp_type == LLCP_CHAN_MAP))) ||
(conn->llcp_cu.req != conn->llcp_cu.ack)) {
lll->latency_event = 0;
}
@@ -1583,7 +1588,7 @@ static int init_reset(void)
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
/* Initialize the DLE defaults */
default_tx_octets = PDU_DC_PAYLOAD_SIZE_MIN;
default_tx_time = PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, 0);
default_tx_time = PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M);
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
#if defined(CONFIG_BT_CTLR_PHY)
@@ -2494,7 +2499,8 @@ static inline void event_enc_reject_prep(struct ll_conn *conn,
pdu->ll_id = PDU_DATA_LLID_CTRL;
if (conn->common.fex_valid &&
(conn->llcp_feature.features & BIT(BT_LE_FEAT_BIT_EXT_REJ_IND))) {
(conn->llcp_feature.features_conn &
BIT(BT_LE_FEAT_BIT_EXT_REJ_IND))) {
struct pdu_data_llctrl_reject_ext_ind *p;
pdu->llctrl.opcode = PDU_DATA_LLCTRL_TYPE_REJECT_EXT_IND;
@@ -2722,7 +2728,7 @@ static inline void event_fex_prep(struct ll_conn *conn)
pdu->llctrl.opcode = PDU_DATA_LLCTRL_TYPE_FEATURE_RSP;
(void)memset(&pdu->llctrl.feature_rsp.features[0], 0x00,
sizeof(pdu->llctrl.feature_rsp.features));
sys_put_le24(conn->llcp_feature.features,
sys_put_le24(conn->llcp_feature.features_peer,
pdu->llctrl.feature_req.features);
/* enqueue feature rsp structure into rx queue */
@@ -2740,7 +2746,7 @@ static inline void event_fex_prep(struct ll_conn *conn)
conn->llcp_feature.ack--;
/* use initial feature bitmap */
conn->llcp_feature.features = LL_FEAT;
conn->llcp_feature.features_conn = LL_FEAT;
/* place the feature exchange req packet as next in tx queue */
pdu->ll_id = PDU_DATA_LLID_CTRL;
@@ -2752,7 +2758,7 @@ static inline void event_fex_prep(struct ll_conn *conn)
(void)memset(&pdu->llctrl.feature_req.features[0],
0x00,
sizeof(pdu->llctrl.feature_req.features));
sys_put_le24(conn->llcp_feature.features,
sys_put_le24(conn->llcp_feature.features_conn,
pdu->llctrl.feature_req.features);
ctrl_tx_enqueue(conn, tx);
@@ -3157,14 +3163,14 @@ static inline void dle_max_time_get(const struct ll_conn *conn,
#if defined(CONFIG_BT_CTLR_PHY)
#if defined(CONFIG_BT_CTLR_PHY_CODED)
feature_coded_phy = (conn->llcp_feature.features &
feature_coded_phy = (conn->llcp_feature.features_conn &
BIT(BT_LE_FEAT_BIT_PHY_CODED));
#else
feature_coded_phy = 0;
#endif
#if defined(CONFIG_BT_CTLR_PHY_2M)
feature_phy_2m = (conn->llcp_feature.features &
feature_phy_2m = (conn->llcp_feature.features_conn &
BIT(BT_LE_FEAT_BIT_PHY_2M));
#else
feature_phy_2m = 0;
@@ -3176,31 +3182,31 @@ static inline void dle_max_time_get(const struct ll_conn *conn,
if (!conn->common.fex_valid ||
(!feature_coded_phy && !feature_phy_2m)) {
rx_time = PKT_US(LL_LENGTH_OCTETS_RX_MAX, 0);
rx_time = PKT_US(LL_LENGTH_OCTETS_RX_MAX, PHY_1M);
#if defined(CONFIG_BT_CTLR_PHY)
tx_time = MAX(MIN(PKT_US(LL_LENGTH_OCTETS_RX_MAX, 0),
tx_time = MAX(MIN(PKT_US(LL_LENGTH_OCTETS_RX_MAX, PHY_1M),
conn->default_tx_time),
PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, 0));
PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M));
#else /* !CONFIG_BT_CTLR_PHY */
tx_time = PKT_US(conn->default_tx_octets, 0);
tx_time = PKT_US(conn->default_tx_octets, PHY_1M);
#endif /* !CONFIG_BT_CTLR_PHY */
#if defined(CONFIG_BT_CTLR_PHY)
#if defined(CONFIG_BT_CTLR_PHY_CODED)
} else if (feature_coded_phy) {
rx_time = MAX(PKT_US(LL_LENGTH_OCTETS_RX_MAX, BIT(2)),
PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, BIT(2)));
tx_time = MIN(PKT_US(LL_LENGTH_OCTETS_RX_MAX, BIT(2)),
rx_time = MAX(PKT_US(LL_LENGTH_OCTETS_RX_MAX, PHY_CODED),
PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_CODED));
tx_time = MIN(PKT_US(LL_LENGTH_OCTETS_RX_MAX, PHY_CODED),
conn->default_tx_time);
tx_time = MAX(PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, 0), tx_time);
tx_time = MAX(PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M), tx_time);
#endif /* CONFIG_BT_CTLR_PHY_CODED */
#if defined(CONFIG_BT_CTLR_PHY_2M)
} else if (feature_phy_2m) {
rx_time = MAX(PKT_US(LL_LENGTH_OCTETS_RX_MAX, BIT(1)),
PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, BIT(1)));
tx_time = MAX(PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, 0),
MIN(PKT_US(LL_LENGTH_OCTETS_RX_MAX, BIT(1)),
rx_time = MAX(PKT_US(LL_LENGTH_OCTETS_RX_MAX, PHY_2M),
PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_2M));
tx_time = MAX(PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M),
MIN(PKT_US(LL_LENGTH_OCTETS_RX_MAX, PHY_2M),
conn->default_tx_time));
#endif /* CONFIG_BT_CTLR_PHY_2M */
#endif /* CONFIG_BT_CTLR_PHY */
@@ -3342,8 +3348,8 @@ static inline void event_len_prep(struct ll_conn *conn)
lr->max_tx_octets = sys_cpu_to_le16(tx_octets);
#if !defined(CONFIG_BT_CTLR_PHY)
lr->max_rx_time =
sys_cpu_to_le16(PKT_US(lll->max_rx_octets, 0));
lr->max_tx_time = sys_cpu_to_le16(PKT_US(tx_octets, 0));
sys_cpu_to_le16(PKT_US(lll->max_rx_octets, PHY_1M));
lr->max_tx_time = sys_cpu_to_le16(PKT_US(tx_octets, PHY_1M));
#else /* CONFIG_BT_CTLR_PHY */
lr->max_rx_time = sys_cpu_to_le16(lll->max_rx_time);
lr->max_tx_time = sys_cpu_to_le16(tx_time);
@@ -4002,12 +4008,28 @@ static inline u32_t feat_get(u8_t *features)
return feat;
}
/*
* Perform a logical and on octet0 and keep the remaining bits of the
* first input parameter
*/
static inline u32_t feat_land_octet0(u32_t feat_to_keep, u32_t feat_octet0)
{
u32_t feat_result;
feat_result = feat_to_keep & feat_octet0;
feat_result &= 0xFF;
feat_result |= feat_to_keep & LL_FEAT_FILTER_OCTET0;
return feat_result;
}
static int feature_rsp_send(struct ll_conn *conn, struct node_rx_pdu *rx,
struct pdu_data *pdu_rx)
{
struct pdu_data_llctrl_feature_req *req;
struct node_tx *tx;
struct pdu_data *pdu_tx;
u32_t feat;
/* acquire tx mem */
tx = mem_acquire(&mem_conn_tx_ctrl.free);
@@ -4017,7 +4039,14 @@ static int feature_rsp_send(struct ll_conn *conn, struct node_rx_pdu *rx,
/* AND the feature set to get Feature USED */
req = &pdu_rx->llctrl.feature_req;
conn->llcp_feature.features &= feat_get(&req->features[0]);
conn->llcp_feature.features_conn &= feat_get(&req->features[0]);
/*
* Get all the features of peer, except octet 0.
* Octet 0 is the actual features used on the link
* See BTCore V5.2, Vol. 6, Part B, chapter 5.1.4
*/
conn->llcp_feature.features_peer =
feat_land_octet0(feat_get(&req->features[0]), LL_FEAT);
/* features exchanged */
conn->common.fex_valid = 1U;
@@ -4026,12 +4055,16 @@ static int feature_rsp_send(struct ll_conn *conn, struct node_rx_pdu *rx,
pdu_tx = (void *)tx->pdu;
pdu_tx->ll_id = PDU_DATA_LLID_CTRL;
pdu_tx->len = offsetof(struct pdu_data_llctrl, feature_rsp) +
sizeof(struct pdu_data_llctrl_feature_rsp);
sizeof(struct pdu_data_llctrl_feature_rsp);
pdu_tx->llctrl.opcode = PDU_DATA_LLCTRL_TYPE_FEATURE_RSP;
(void)memset(&pdu_tx->llctrl.feature_rsp.features[0], 0x00,
sizeof(pdu_tx->llctrl.feature_rsp.features));
sys_put_le24(conn->llcp_feature.features,
pdu_tx->llctrl.feature_req.features);
/*
* On feature response we send the local supported features.
* See BTCore V5.2 VOl 6 Part B, chapter 5.1.4
*/
feat = feat_land_octet0(LL_FEAT, conn->llcp_feature.features_conn);
sys_put_le24(feat, pdu_tx->llctrl.feature_rsp.features);
ctrl_tx_sec_enqueue(conn, tx);
@@ -4048,7 +4081,14 @@ static void feature_rsp_recv(struct ll_conn *conn, struct pdu_data *pdu_rx)
rsp = &pdu_rx->llctrl.feature_rsp;
/* AND the feature set to get Feature USED */
conn->llcp_feature.features &= feat_get(&rsp->features[0]);
conn->llcp_feature.features_conn &= feat_get(&rsp->features[0]);
/*
* Get all the features of peer, except octet 0.
* Octet 0 is the actual features used on the link
* See BTCore V5.2, Vol. 6, Part B, chapter 5.1.4
*/
conn->llcp_feature.features_peer =
feat_land_octet0(feat_get(&rsp->features[0]), LL_FEAT);
/* features exchanged */
conn->common.fex_valid = 1U;
@@ -4290,9 +4330,9 @@ static inline int reject_ind_dle_recv(struct ll_conn *conn,
lr->max_tx_octets = sys_cpu_to_le16(conn->lll.max_tx_octets);
#if !defined(CONFIG_BT_CTLR_PHY)
lr->max_rx_time =
sys_cpu_to_le16(PKT_US(conn->lll.max_rx_octets, 0));
sys_cpu_to_le16(PKT_US(conn->lll.max_rx_octets, PHY_1M));
lr->max_tx_time =
sys_cpu_to_le16(PKT_US(conn->lll.max_tx_octets, 0));
sys_cpu_to_le16(PKT_US(conn->lll.max_tx_octets, PHY_1M));
#else /* CONFIG_BT_CTLR_PHY */
lr->max_rx_time = sys_cpu_to_le16(conn->lll.max_rx_time);
lr->max_tx_time = sys_cpu_to_le16(conn->lll.max_tx_time);
@@ -4446,9 +4486,9 @@ static void length_resp_send(struct ll_conn *conn, struct node_tx *tx,
#if !defined(CONFIG_BT_CTLR_PHY)
pdu_tx->llctrl.length_rsp.max_rx_time =
sys_cpu_to_le16(PKT_US(eff_rx_octets, 0));
sys_cpu_to_le16(PKT_US(eff_rx_octets, PHY_1M));
pdu_tx->llctrl.length_rsp.max_tx_time =
sys_cpu_to_le16(PKT_US(eff_tx_octets, 0));
sys_cpu_to_le16(PKT_US(eff_tx_octets, PHY_1M));
#else /* CONFIG_BT_CTLR_PHY */
pdu_tx->llctrl.length_rsp.max_rx_time = sys_cpu_to_le16(eff_rx_time);
pdu_tx->llctrl.length_rsp.max_tx_time = sys_cpu_to_le16(eff_tx_time);
@@ -4488,8 +4528,7 @@ static inline int length_req_rsp_recv(struct ll_conn *conn, memq_link_t *link,
if (/* Local idle, and Peer request then complete the Peer procedure
* with response.
*/
((conn->llcp_length.req == conn->llcp_length.ack) &&
(pdu_rx->llctrl.opcode == PDU_DATA_LLCTRL_TYPE_LENGTH_REQ)) ||
((conn->llcp_length.req == conn->llcp_length.ack) && tx) ||
/* or Local has active... */
((conn->llcp_length.req != conn->llcp_length.ack) &&
/* with Local requested and Peer request then complete the
@@ -4497,17 +4536,12 @@ static inline int length_req_rsp_recv(struct ll_conn *conn, memq_link_t *link,
*/
((((conn->llcp_length.state == LLCP_LENGTH_STATE_REQ) ||
(conn->llcp_length.state == LLCP_LENGTH_STATE_REQ_ACK_WAIT)) &&
(pdu_rx->llctrl.opcode ==
PDU_DATA_LLCTRL_TYPE_LENGTH_REQ)) ||
tx) ||
/* with Local waiting for response, and Peer response then
* complete the Local procedure or Peer request then complete the
* Peer procedure with response.
*/
((conn->llcp_length.state == LLCP_LENGTH_STATE_RSP_WAIT) &&
((pdu_rx->llctrl.opcode ==
PDU_DATA_LLCTRL_TYPE_LENGTH_RSP) ||
(pdu_rx->llctrl.opcode ==
PDU_DATA_LLCTRL_TYPE_LENGTH_REQ)))))) {
(conn->llcp_length.state == LLCP_LENGTH_STATE_RSP_WAIT)))) {
struct pdu_data_llctrl_length_req *lr;
u16_t max_rx_octets;
u16_t max_tx_octets;
@@ -4546,7 +4580,7 @@ static inline int length_req_rsp_recv(struct ll_conn *conn, memq_link_t *link,
lr_rx_time = sys_le16_to_cpu(lr->max_rx_time);
lr_tx_time = sys_le16_to_cpu(lr->max_tx_time);
if (lr_rx_time >= PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, 0)) {
if (lr_rx_time >= PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M)) {
eff_tx_time = MIN(lr_rx_time, max_tx_time);
#if defined(CONFIG_BT_CTLR_PHY_CODED)
eff_tx_time = MAX(eff_tx_time,
@@ -4558,7 +4592,7 @@ static inline int length_req_rsp_recv(struct ll_conn *conn, memq_link_t *link,
/* use the minimal of our max supported and
* peer max_tx_time
*/
if (lr_tx_time >= PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, 0)) {
if (lr_tx_time >= PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M)) {
eff_rx_time = MIN(lr_tx_time, max_rx_time);
#if defined(CONFIG_BT_CTLR_PHY_CODED)
eff_rx_time = MAX(eff_rx_time,
@@ -4662,18 +4696,29 @@ static inline int length_req_rsp_recv(struct ll_conn *conn, memq_link_t *link,
#if !defined(CONFIG_BT_CTLR_PHY)
lr->max_rx_time =
sys_cpu_to_le16(PKT_US(eff_rx_octets, 0));
sys_cpu_to_le16(PKT_US(eff_rx_octets, PHY_1M));
lr->max_tx_time =
sys_cpu_to_le16(PKT_US(eff_tx_octets, 0));
sys_cpu_to_le16(PKT_US(eff_tx_octets, PHY_1M));
#else /* CONFIG_BT_CTLR_PHY */
lr->max_rx_time = sys_cpu_to_le16(eff_rx_time);
lr->max_tx_time = sys_cpu_to_le16(eff_tx_time);
#endif /* CONFIG_BT_CTLR_PHY */
}
} else {
/* Drop response with no Local initiated request. */
LL_ASSERT(pdu_rx->llctrl.opcode ==
PDU_DATA_LLCTRL_TYPE_LENGTH_RSP);
/* Drop response with no Local initiated request and duplicate
* requests.
*/
if (pdu_rx->llctrl.opcode != PDU_DATA_LLCTRL_TYPE_LENGTH_RSP) {
mem_release(tx, &mem_conn_tx_ctrl.free);
/* Defer new request if previous in resize state */
if (conn->llcp_length.state ==
LLCP_LENGTH_STATE_RESIZE) {
return -EBUSY;
}
}
return 0;
}
send_length_resp:
@@ -5394,7 +5439,9 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
#endif /* CONFIG_BT_CTLR_SLAVE_FEAT_REQ */
case PDU_DATA_LLCTRL_TYPE_FEATURE_RSP:
if (!pdu_len_cmp(PDU_DATA_LLCTRL_TYPE_FEATURE_RSP,
if ((!IS_ENABLED(CONFIG_BT_CTLR_SLAVE_FEAT_REQ) &&
conn->lll.role) ||
!pdu_len_cmp(PDU_DATA_LLCTRL_TYPE_FEATURE_RSP,
pdu_rx->len)) {
goto ull_conn_rx_unknown_rsp_send;
}

View File

@@ -17,6 +17,9 @@
*/
#define PAYLOAD_OVERHEAD_SIZE (2 + 4)
#define PHY_1M BIT(0)
#define PHY_2M BIT(1)
#define PHY_CODED BIT(2)
#if defined(CONFIG_BT_CTLR_PHY_CODED)
#define CODED_PHY_PREAMBLE_TIME_US (80)
#define CODED_PHY_ACCESS_ADDRESS_TIME_US (256)
@@ -33,23 +36,23 @@
CODED_PHY_CRC_SIZE + \
CODED_PHY_TERM2_SIZE) * 8)
#define PKT_US(octets, phy) (((phy) & BIT(2)) ? \
#define PKT_US(octets, phy) (((phy) & PHY_CODED) ? \
(CODED_PHY_PREAMBLE_TIME_US + \
FEC_BLOCK1_TIME_US + \
FEC_BLOCK2_TIME_US(octets)) : \
(((PREAMBLE_SIZE(1) + \
(((PREAMBLE_SIZE(phy) + \
ACCESS_ADDR_SIZE + \
PAYLOAD_OVERHEAD_SIZE + \
(octets) + \
CRC_SIZE) * 8) / \
BIT(((phy) & 0x03) >> 1)))
#else /* !CONFIG_BT_CTLR_PHY_CODED */
#define PKT_US(octets, phy) (((PREAMBLE_SIZE(1) + \
#define PKT_US(octets, phy) ((((PREAMBLE_SIZE(phy)) + \
ACCESS_ADDR_SIZE + \
PAYLOAD_OVERHEAD_SIZE + \
(octets) + \
CRC_SIZE) * 8) / \
BIT(((phy) & 0x03) >> 1))
BIT(((phy) & 0x03) >> 1))
#endif /* !CONFIG_BT_CTLR_PHY_CODED */
struct ll_conn *ll_conn_acquire(void);

View File

@@ -140,7 +140,8 @@ struct ll_conn {
struct {
u8_t req;
u8_t ack;
u32_t features;
u32_t features_conn;
u32_t features_peer;
} llcp_feature;
struct {

View File

@@ -127,8 +127,8 @@ u8_t ll_create_connection(u16_t scan_interval, u16_t scan_window,
conn_lll->max_rx_octets = PDU_DC_PAYLOAD_SIZE_MIN;
#if defined(CONFIG_BT_CTLR_PHY)
conn_lll->max_tx_time = PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, 0);
conn_lll->max_rx_time = PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, 0);
conn_lll->max_tx_time = PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M);
conn_lll->max_rx_time = PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M);
#endif /* CONFIG_BT_CTLR_PHY */
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
@@ -197,7 +197,8 @@ u8_t ll_create_connection(u16_t scan_interval, u16_t scan_window,
conn->llcp_rx = NULL;
conn->llcp_cu.req = conn->llcp_cu.ack = 0;
conn->llcp_feature.req = conn->llcp_feature.ack = 0;
conn->llcp_feature.features = LL_FEAT;
conn->llcp_feature.features_conn = LL_FEAT;
conn->llcp_feature.features_peer = 0;
conn->llcp_version.req = conn->llcp_version.ack = 0;
conn->llcp_version.tx = conn->llcp_version.rx = 0U;
conn->llcp_terminate.reason_peer = 0U;

View File

@@ -79,7 +79,13 @@ void ull_slave_setup(memq_link_t *link, struct node_rx_hdr *rx,
sizeof(lll->data_chan_map));
lll->data_chan_count = util_ones_count_get(&lll->data_chan_map[0],
sizeof(lll->data_chan_map));
if (lll->data_chan_count < 2) {
return;
}
lll->data_chan_hop = pdu_adv->connect_ind.hop;
if ((lll->data_chan_hop < 5) || (lll->data_chan_hop > 16)) {
return;
}
interval = sys_le16_to_cpu(pdu_adv->connect_ind.interval);
lll->interval = interval;
lll->latency = sys_le16_to_cpu(pdu_adv->connect_ind.latency);

View File

@@ -629,15 +629,10 @@ static u32_t ticker_dequeue(struct ticker_instance *instance, u8_t id)
static u8_t ticker_resolve_collision(struct ticker_node *nodes,
struct ticker_node *ticker)
{
u8_t skipped = 0;
s32_t lazy_current = ticker->lazy_current;
if ((ticker->priority != TICKER_PRIORITY_CRITICAL) &&
(ticker->next != TICKER_NULL)) {
s32_t lazy_current = ticker->lazy_current;
if (ticker->lazy_periodic > lazy_current) {
/* Programmed latency must be respected */
skipped = 1;
} else if ((ticker->priority != TICKER_PRIORITY_CRITICAL) &&
(ticker->next != TICKER_NULL)) {
/* Check if this ticker node will starve next node which has
* latency or higher priority
*/
@@ -645,7 +640,7 @@ static u8_t ticker_resolve_collision(struct ticker_node *nodes,
lazy_current -= ticker->lazy_periodic;
}
u8_t id_head = ticker->next;
u32_t acc_ticks_to_expire = 0;
u32_t acc_ticks_to_expire = 0U;
/* Age is time since last expiry */
u32_t current_age = ticker->ticks_periodic +
@@ -661,7 +656,7 @@ static u8_t ticker_resolve_collision(struct ticker_node *nodes,
}
/* We only care about nodes with slot reservation */
if (ticker_next->ticks_slot == 0) {
if (ticker_next->ticks_slot == 0U) {
id_head = ticker_next->next;
continue;
}
@@ -716,13 +711,13 @@ static u8_t ticker_resolve_collision(struct ticker_node *nodes,
(next_has_priority && !current_is_older) ||
(equal_priority && next_is_older))) {
/* This node must be skipped - check window */
skipped = 1;
break;
return 1U;
}
id_head = ticker_next->next;
}
}
return skipped;
return 0U;
}
#endif /* !CONFIG_BT_TICKER_COMPATIBILITY_MODE */
@@ -998,7 +993,6 @@ static u8_t ticker_remainder_inc(struct ticker_node *ticker)
#endif
}
#if defined(CONFIG_BT_TICKER_COMPATIBILITY_MODE)
/**
* @brief Decrement remainder
*
@@ -1028,7 +1022,6 @@ static u8_t ticker_remainder_dec(struct ticker_node *ticker)
return 0;
#endif
}
#endif /* CONFIG_BT_TICKER_COMPATIBILITY_MODE */
/**
* @brief Invoke user operation callback
@@ -1084,7 +1077,6 @@ static inline void ticker_job_node_update(struct ticker_node *ticker,
if ((ticker->ticks_periodic != 0U) &&
(user_op->params.update.lazy != 0U)) {
user_op->params.update.lazy--;
#if defined(CONFIG_BT_TICKER_COMPATIBILITY_MODE)
while ((ticks_to_expire > ticker->ticks_periodic) &&
(ticker->lazy_current > user_op->params.update.lazy)) {
ticks_to_expire -= ticker->ticks_periodic +
@@ -1097,7 +1089,6 @@ static inline void ticker_job_node_update(struct ticker_node *ticker,
ticker_remainder_inc(ticker);
ticker->lazy_current++;
}
#endif /* CONFIG_BT_TICKER_COMPATIBILITY_MODE */
ticker->lazy_periodic = user_op->params.update.lazy;
}
@@ -1331,9 +1322,18 @@ static inline void ticker_job_worker_bh(struct ticker_instance *instance,
struct ticker_node *node;
u32_t ticks_expired;
#if !defined(CONFIG_BT_TICKER_COMPATIBILITY_MODE)
u32_t ticks_latency;
u32_t ticks_now;
ticks_now = cntr_cnt_get();
ticks_latency = ticker_ticks_diff_get(ticks_now, ticks_previous);
#endif /* !CONFIG_BT_TICKER_COMPATIBILITY_MODE */
node = &instance->nodes[0];
ticks_expired = 0U;
while (instance->ticker_id_head != TICKER_NULL) {
u8_t is_must_expire_skip = 0U;
struct ticker_node *ticker;
u32_t ticks_to_expire;
u8_t id_expired;
@@ -1354,32 +1354,29 @@ static inline void ticker_job_worker_bh(struct ticker_instance *instance,
ticks_expired += ticks_to_expire;
#if !defined(CONFIG_BT_TICKER_COMPATIBILITY_MODE)
if (ticker->lazy_current != 0U &&
!TICKER_RESCHEDULE_PENDING(ticker)) {
ticks_latency -= ticks_to_expire;
is_must_expire_skip = (ticker->must_expire &&
(ticker->lazy_current != 0U));
#endif /* !CONFIG_BT_TICKER_COMPATIBILITY_MODE */
/* decrement ticks_slot_previous */
if (instance->ticks_slot_previous > ticks_to_expire) {
instance->ticks_slot_previous -= ticks_to_expire;
} else {
instance->ticker_id_slot_previous = TICKER_NULL;
instance->ticks_slot_previous = 0U;
} else
#endif /* !CONFIG_BT_TICKER_COMPATIBILITY_MODE */
{
/* decrement ticks_slot_previous */
if (instance->ticks_slot_previous > ticks_to_expire) {
instance->ticks_slot_previous -=
ticks_to_expire;
} else {
instance->ticker_id_slot_previous = TICKER_NULL;
instance->ticks_slot_previous = 0U;
}
}
/* If a reschedule is set pending, we will need to keep
* the slot_previous information
*/
if (!TICKER_RESCHEDULE_PENDING(ticker) &&
ticker->ticks_slot != 0U) {
instance->ticker_id_slot_previous =
id_expired;
instance->ticks_slot_previous =
ticker->ticks_slot;
}
/* If a reschedule is set pending, we will need to keep
* the slot_previous information
*/
if ((ticker->ticks_slot != 0U) &&
(((ticker->req - ticker->ack) & 0xff) == 2U) &&
!is_must_expire_skip &&
!TICKER_RESCHEDULE_PENDING(ticker)) {
instance->ticker_id_slot_previous = id_expired;
instance->ticks_slot_previous = ticker->ticks_slot;
}
/* ticker expired, set ticks_to_expire zero */
@@ -1398,12 +1395,62 @@ static inline void ticker_job_worker_bh(struct ticker_instance *instance,
* restarted
*/
ticker->ticks_to_expire = ticks_elapsed;
/* Reset ticker state, so that its put
* back in requested state later down
* in the code.
*/
ticker->req = ticker->ack;
} else {
/* Reload ticks_to_expire with one period */
ticker->ticks_to_expire =
ticker->ticks_periodic;
ticker->ticks_to_expire +=
ticker_remainder_inc(ticker);
u16_t lazy_periodic;
u32_t count;
u16_t lazy;
/* If not skipped, apply lazy_periodic */
if (!ticker->lazy_current) {
lazy_periodic = ticker->lazy_periodic;
} else {
lazy_periodic = 0U;
/* Reset ticker state, so that its put
* back in requested state later down
* in the code.
*/
ticker->req = ticker->ack;
}
/* Reload ticks_to_expire with atleast one
* period.
*/
ticks_to_expire = 0U;
count = 1 + lazy_periodic;
while (count--) {
ticks_to_expire +=
ticker->ticks_periodic;
ticks_to_expire +=
ticker_remainder_inc(ticker);
}
/* Skip intervals that have elapsed w.r.t.
* current ticks.
*/
lazy = 0U;
if (!ticker->must_expire) {
while (ticks_to_expire <
ticks_latency) {
ticks_to_expire +=
ticker->ticks_periodic;
ticks_to_expire +=
ticker_remainder_inc(ticker);
lazy++;
}
}
/* Use the calculated ticks to expire and
* laziness.
*/
ticker->ticks_to_expire = ticks_to_expire;
ticker->lazy_current += (lazy_periodic + lazy);
}
ticks_to_expire_prep(ticker, instance->ticks_current,
@@ -2049,6 +2096,7 @@ static inline void ticker_job_compare_update(struct ticker_instance *instance,
if (instance->ticker_id_head == TICKER_NULL) {
if (cntr_stop() == 0) {
instance->ticks_slot_previous = 0U;
instance->ticks_current = cntr_cnt_get();
}
return;
}

View File

@@ -4303,8 +4303,11 @@ static int cf_set(const char *name, size_t len_rd, settings_read_cb read_cb,
cfg = find_cf_cfg(NULL);
if (!cfg) {
BT_ERR("Unable to restore CF: no cfg left");
return 0;
return -ENOMEM;
}
cfg->id = id;
bt_addr_le_copy(&cfg->peer, &addr);
}
if (len_rd) {
@@ -4358,6 +4361,7 @@ static int db_hash_commit(void)
if (!memcmp(stored_hash, db_hash, sizeof(stored_hash))) {
BT_DBG("Database Hash matches");
k_delayed_work_cancel(&gatt_sc.work);
atomic_clear_bit(gatt_sc.flags, SC_RANGE_CHANGED);
return 0;
}

View File

@@ -4097,8 +4097,7 @@ static void send_cmd(void)
if (err) {
BT_ERR("Unable to send to driver (err %d)", err);
k_sem_give(&bt_dev.ncmd_sem);
hci_cmd_done(cmd(buf)->opcode, BT_HCI_ERR_UNSPECIFIED,
NULL);
hci_cmd_done(cmd(buf)->opcode, BT_HCI_ERR_UNSPECIFIED, buf);
net_buf_unref(bt_dev.sent_cmd);
bt_dev.sent_cmd = NULL;
net_buf_unref(buf);

View File

@@ -1793,10 +1793,13 @@ static void smp_pairing_complete(struct bt_smp *smp, u8_t status)
} else {
u8_t auth_err = auth_err_get(status);
/*
* Clear the key pool entry in case of pairing failure.
/* Clear the key pool entry in case of pairing failure if the
* keys already existed before the pairing procedure or the
* pairing failed during key distribution.
*/
if (smp->chan.chan.conn->le.keys) {
if (smp->chan.chan.conn->le.keys &&
(!smp->chan.chan.conn->le.keys->enc_size ||
atomic_test_bit(smp->flags, SMP_FLAG_KEYS_DISTR))) {
bt_keys_clear(smp->chan.chan.conn->le.keys);
smp->chan.chan.conn->le.keys = NULL;
}

View File

@@ -152,7 +152,7 @@ static void net_key_status(struct bt_mesh_model *model,
struct net_buf_simple *buf)
{
struct net_key_param *param;
u16_t net_idx, app_idx;
u16_t net_idx;
u8_t status;
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
@@ -165,7 +165,7 @@ static void net_key_status(struct bt_mesh_model *model,
}
status = net_buf_simple_pull_u8(buf);
key_idx_unpack(buf, &net_idx, &app_idx);
net_idx = net_buf_simple_pull_le16(buf) & 0xfff;
param = cli->op_param;
if (param->net_idx != net_idx) {

View File

@@ -17,6 +17,7 @@ LOG_MODULE_REGISTER(net_coap, CONFIG_COAP_LOG_LEVEL);
#include <zephyr/types.h>
#include <sys/byteorder.h>
#include <sys/math_extras.h>
#include <net/net_ip.h>
#include <net/net_core.h>
@@ -469,7 +470,9 @@ static int parse_option(u8_t *data, u16_t offset, u16_t *pos,
return -EINVAL;
}
*opt_len += hdr_len;
if (u16_add_overflow(*opt_len, hdr_len, opt_len)) {
return -EINVAL;
}
}
if (len > COAP_OPTION_NO_EXT) {
@@ -480,11 +483,15 @@ static int parse_option(u8_t *data, u16_t offset, u16_t *pos,
return -EINVAL;
}
*opt_len += hdr_len;
if (u16_add_overflow(*opt_len, hdr_len, opt_len)) {
return -EINVAL;
}
}
*opt_delta += delta;
*opt_len += len;
if (u16_add_overflow(*opt_delta, delta, opt_delta) ||
u16_add_overflow(*opt_len, len, opt_len)) {
return -EINVAL;
}
if (r == 0) {
if (len == 0U) {
@@ -519,7 +526,10 @@ static int parse_option(u8_t *data, u16_t offset, u16_t *pos,
return -EINVAL;
}
} else {
*pos += len;
if (u16_add_overflow(*pos, len, pos)) {
return -EINVAL;
}
r = max_len - *pos;
}