Compare commits

...

33 Commits

Author SHA1 Message Date
Roman Vaughan
fc728c040d tests: fs: Ensure file_path includes max file name length
A hardcoded path lenth of 80 will not be able to suppor the full length
of 255 when LFN is enabled. This does produce a compiler error,
thankfully, this is only applicable to the test cases.

Signed-off-by: Roman Vaughan <nzsmartie@gmail.com>
Signed-off-by: David Brown <david.brown@linaro.org>
2020-11-17 16:48:29 -05:00
Roman Vaughan
4bc83f3da4 fs: Set MAX_FILE_NAME appropiately with LFN and FATFS
Try to define MAX_FILE_NAME to the appropriate max length based on the
selected filesystm. Otherwise fallback to a standard filename of 12
(made up of 8.3 : <filename>.<extension>)

Signed-off-by: Roman Vaughan <nzsmartie@gmail.com>
Signed-off-by: David Brown <david.brown@linaro.org>
2020-11-17 16:48:29 -05:00
Roman Vaughan
537d11f423 tests: fs: Add test case for LFN with FATFS
Rerun the same test but with CONFIG_FS_FATFS_LFN=Y and
with a long filename.

Signed-off-by: Roman Vaughan <nzsmartie@gmail.com>
Signed-off-by: David Brown <david.brown@linaro.org>
2020-11-17 16:48:29 -05:00
Vinayak Kariappa Chettimada
1fe11352b2 Bluetooth: controller: Add explicit opcode check in unknown rsp PDU
Add explicit opcode check when handling received unknown
response PDU.

Without this, for example, an in progress Data Length Update
procedure state was reset when receiving an unknown response
to slave initiated feature request.

Fixes #26252.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2020-11-17 16:48:03 -05:00
Gerson Fernando Budke
ec6db60015 lib: updatehub: Add flash_img_init return value check
The flash_img_int return value is not checked for fail conditions.
This can result on useless download attempts once image will not
be properly recorded. Add return value check and on error execute
default treatment.

Fixes #26992.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
2020-11-17 16:47:50 -05:00
Gerson Fernando Budke
c2e60a4e01 lib: updatehub: Fix out-of-bounds access
The struct pollfd context variable is not proper initialized and index
is out-of-bounds. Adjusts index to be inside scope boundary.

Fixes #26993.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
2020-11-17 16:47:50 -05:00
Gerson Fernando Budke
44fc9dcada lib: updatehub: Fix getaddrinfo resource leak
Add missing freeaddrinfo to fix memory leak.

Fixes #26994.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
2020-11-17 16:47:50 -05:00
Gerson Fernando Budke
69c5669199 lib: updatehub: Add download block check
The current CoAP implementation not perform any checks including
duplicated packets. This add block sequency verification and a
timer to ensures that slow networks works apropriately.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
2020-11-17 16:47:50 -05:00
Gerson Fernando Budke
29f883a706 lib: updatehub: Kconfig: Add coap block size option
Allow select max CoAP block size for exchange data using coap protocol.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
2020-11-17 16:47:50 -05:00
Gerson Fernando Budke
f0fb867b2e lib: updatehub: Kconfig: Add coap max retry option
The current implementation uses a fixed value for max retries. That
value could be good for an wired network like Ethernet. However,
wireless network can suffer with higher packet collision, low reception
signal etc. This refacts the variable to be defined at Kconfig. This
way max retries can be adjust conform the current media.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
2020-11-17 16:47:50 -05:00
Gerson Fernando Budke
6e60ede6a9 lib: updatehub: Init metadata variable
Init metadata variable to a defined state.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
2020-11-17 16:47:50 -05:00
Gerson Fernando Budke
9f3afd3306 lib: updatehub: Init hints variable
The hints variable is used without a defined state. This fill the struct
with zeros to set variable at a well known state.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
2020-11-17 16:47:50 -05:00
Gerson Fernando Budke
5e3922e4d7 lib: updatehub: Add log level
Current log only prints default log level. Add LOG_LEVEL at updatehub
to switch between log variations based on CONFIG_UPDATEHUB_LOG_LEVEL.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
2020-11-17 16:47:50 -05:00
Gerson Fernando Budke
89241536d8 net: lwm2m: Refactor to use coap_get_option_int
Small clean-up to use coap_get_option_int.

Signed-off-by: Gerson Fernando Budke <nandojve@gmail.com>
2020-11-17 16:47:50 -05:00
Gerson Fernando Budke
a88ead5227 samples: coap_server: Refactor to use coap_get_option_int
Small clean-up to use coap_get_option_int.

Signed-off-by: Gerson Fernando Budke <nandojve@gmail.com>
2020-11-17 16:47:50 -05:00
Gerson Fernando Budke
0fb9742847 net: coap: Rem macros that uses coap_get_option_int
Clean up and remove macros that uses coap_get_option_int.

Signed-off-by: Gerson Fernando Budke <nandojve@gmail.com>
2020-11-17 16:47:50 -05:00
Gerson Fernando Budke
068cc03bc8 net: coap: Add coap_get_option_int public method
Any CoAP implementation when use at least block transfer or is a server
side need access some CoAP options as integer values. This add a method
at public interface and defines for block wise operations to avoid code
useless code duplication.

Signed-off-by: Gerson Fernando Budke <nandojve@gmail.com>
2020-11-17 16:47:50 -05:00
Gerson Fernando Budke
aa9248f5b7 samples: net: updatehub: Increase shell stack
When running shell commands updatehub alloc data from shell stack.
Increase shell room stack to avoid shell issues.  Memory tuning
should be performed accord with available resources.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
2020-11-17 16:47:33 -05:00
Gerson Fernando Budke
11c5d49073 lib: updatehub: Fix possible deref an uninitialized ptr
There are several references to objects[1] at updatehub_probe function.
The structures are decoded from json, and have a maximum length of 2.
However, if the returned json only has a single element in this array,
this objects[1] value will be uninitialized. Because the structure
contains pointers, these will be uninitialized, causing the code to
reference uninitialized memory as pointers.

Add zeroing memory before passing it to the JSON API and do check if
objects_len field is two.

Fixes #27718.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
2020-11-17 16:47:33 -05:00
Loic Poulain
39717ecf04 drivers: wifi: eswifi: Fix parsing buffer-overflows
There are possible buffer overflows when parsing the ip address and
SSID. Ensure that we never overwrite the ip and SSID buffers.

Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
Signed-off-by: David Brown <david.brown@linaro.org>
2020-11-16 08:36:17 -05:00
Loic Poulain
f798a1daa0 drivers: wifi: eswifi: Add debug shell
Add a esWiFi shell for device specific controls.
For now used to send at commands.

Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
Signed-off-by: David Brown <david.brown@linaro.org>
2020-11-16 08:36:17 -05:00
Loic Poulain
e48fe6bad8 drivers: wifi: eswifi: Use log_strdup for strings
Use log_strdup() helper for logger string parameters.

Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
Signed-off-by: David Brown <david.brown@linaro.org>
2020-11-16 08:36:17 -05:00
Loic Poulain
bd2c163277 drivers: wifi: eswifi: Stop client before starting
Stop any TCP/UDP client session before starting a new one.

Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
Signed-off-by: David Brown <david.brown@linaro.org>
2020-11-16 08:36:17 -05:00
Luiz Augusto von Dentz
54f1a4a6d9 Bluetooth: shell: Add support for printing the write rate
This makes the gatt metrics also available for
gatt write-without-rsp-cb so it now prints the rate of each write:

uart:~$ gatt write-without-response-cb 1e ff 10 10
Write #1: 16 bytes (0 bps)
Write #2: 32 bytes (3445948416 bps)
Write #3: 48 bytes (2596929536 bps)
Write #4: 64 bytes (6400 bps)
Write #5: 80 bytes (8533 bps)
Write #6: 96 bytes (10666 bps)
Write #7: 112 bytes (8533 bps)
Write #8: 128 bytes (9955 bps)
Write #9: 144 bytes (11377 bps)
Write #10: 160 bytes (7680 bps)
Write #11: 176 bytes (8533 bps)
Write #12: 192 bytes (9386 bps)
Write Complete (err 0)
Write #13: 208 bytes (8533 bps)
Write #14: 224 bytes (9244 bps)
Write #15: 240 bytes (9955 bps)
Write #16: 256 bytes (8000 bps)

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2020-11-16 08:34:42 -05:00
Luiz Augusto von Dentz
ac25b935ca Bluetooth: ATT: Fix using of k_fifo_{put,get}
These functions don't work with buffers that do have fragments, instead
this replaces their usage with net_buf_{put,get}.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2020-11-16 08:34:42 -05:00
Luiz Augusto von Dentz
9052e3e99b Bluetooth: ATT: Fix low throughput
ATT_PENDING_SENT does severely impact the throughput since multiple
packets no longer can be scheduled at same time, so instead of always
setting it regardless of the bearer/channel it is now only used for
EATT since that cannot set its own callbacks.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2020-11-16 08:34:42 -05:00
Luiz Augusto von Dentz
9882e76b49 Bluetooth: ATT: Fix not returning error
bt_l2cap_send_cb may fail if there are no context available which means
that the request would not be sent, also due to the use of custom
callback it cannot be queued either so the only option is to return the
error and let the application handle it.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2020-11-16 08:34:42 -05:00
Luiz Augusto von Dentz
b0cecce7d9 Bluetooth: ATT: Fix not processing pending requests
Since the TX semaphore is used for all types of PDUs a request may have
to be put on the request list while there is no pending request pending
which means no response will be generated to trigger att_process,
previously this condition was handled by setting the request as
currently pending and append its buffer to tx_queue but this is no
longer efficient since there could be more than one channel active the
code should try all of them before queueing back to request list.

To fix this the request list will now be processed each time a PDU has
been sent.

Fixes #26070

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2020-11-16 08:34:42 -05:00
Luiz Augusto von Dentz
6821e0b4ae Bluetooth: ATT: Fix overwritting sent callback
ATT channel sent callback shall not be overwritting until the
operation completes as it can result in breaking flow control when
CONFIG_BT_ATT_ENFORCE_FLOW is enabled.

Fixes #25964
Fixes #26071

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2020-11-16 08:34:42 -05:00
Anas Nashif
c0d3c80044 ci: add compliance checking via GH actions
Move check_compliance script to main tree and adapt/use with GH actions.

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2020-06-24 09:41:15 -05:00
Kumar Gala
3a7e510f50 buildkite: Handle case of sanitycheck doing nothing
The junit-annotate step will fail if there are no sanitycheck-*.xml
files to be found which can happen if sanitycheck is run and does
nothing (for example an update to .editorconfig).

Try and create an empty sanitycheck.xml in such a case.

Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
2020-06-23 09:16:41 -05:00
Kumar Gala
906c3367e3 ci: Add initial buildkite ci setup
Add setup to utilize buildkite for CI purposes:

1. .buildkite/hooks/pre-command:
   * Handles getting git checkout setup against upstream repo
   * Setup some west module cache (dirs, clean out files & locks)
   * init dir for ccache

2. .buildkite/hooks/post-command:
   * Report disk usage (meant for possible debugging)

3. .buildkite/pipeline.yml [uses to determine what to do]:
   * setup zephyr env vars
   * set which docker container to use
     (export some local disk caches for git, west modules, and ccache)
   * uses plug to general build annotation on failure (junit-annotate)

4. .buildkite/run.sh [ buildkite wrapper to invoke scripts/ci/run.sh ]

Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
2020-06-22 09:10:06 -05:00
Kumar Gala
b8e08a6395 ci: Update for buildkite environment
* Tweak west_setup:
  - log `west update` to a file to reduce noise in log
  - use `west forall` + `git reset` to make sure files are checked out
    (this is to handle a possible module cache)
* Output when we start sanity_check.  Add a banner for when we run
  sanity_check so it's a bit easier to find in console logs

Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
2020-06-22 09:10:06 -05:00
35 changed files with 2272 additions and 216 deletions

8
.buildkite/hooks/post-command Executable file
View File

@@ -0,0 +1,8 @@
#!/bin/bash
# Copyright (c) 2020 Linaro Limited
#
# SPDX-License-Identifier: Apache-2.0
# report disk usage:
echo "--- $0 disk usage"
df -h

38
.buildkite/hooks/pre-command Executable file
View File

@@ -0,0 +1,38 @@
#!/bin/bash
# Copyright (c) 2020 Linaro Limited
#
# SPDX-License-Identifier: Apache-2.0
# Save off where we started so we can go back there
WORKDIR=${PWD}
if [ -n "${BUILDKITE_PULL_REQUEST_BASE_BRANCH}" ]; then
git fetch -v origin ${BUILDKITE_PULL_REQUEST_BASE_BRANCH}
git checkout FETCH_HEAD
git config --local user.email "builds@zephyrproject.org"
git config --local user.name "Zephyr CI"
git merge --no-edit "${BUILDKITE_COMMIT}" || {
local merge_result=$?
echo "Merge failed: ${merge_result}"
git merge --abort
exit $merge_result
}
fi
mkdir -p /var/lib/buildkite-agent/zephyr-ccache/
# create cache dirs, no-op if they already exist
mkdir -p /var/lib/buildkite-agent/zephyr-module-cache/modules
mkdir -p /var/lib/buildkite-agent/zephyr-module-cache/tools
mkdir -p /var/lib/buildkite-agent/zephyr-module-cache/bootloader
# Clean cache - if it already exists
cd /var/lib/buildkite-agent/zephyr-module-cache
find -type f -not -path "*/.git/*" -not -name ".git" -delete
# Remove any stale locks
find -name index.lock -delete
# return from where we started so we can find pipeline files from
# git repo
cd ${WORKDIR}

28
.buildkite/pipeline.yml Normal file
View File

@@ -0,0 +1,28 @@
steps:
- command:
- .buildkite/run.sh
env:
ZEPHYR_TOOLCHAIN_VARIANT: "zephyr"
ZEPHYR_SDK_INSTALL_DIR: "/opt/sdk/zephyr-sdk-0.11.3"
parallelism: 20
timeout_in_minutes: 120
retry:
manual: true
plugins:
- docker#v3.5.0:
image: "zephyrprojectrtos/ci:v0.11.8"
propagate-environment: true
volumes:
- "/var/lib/buildkite-agent/git-mirrors:/var/lib/buildkite-agent/git-mirrors"
- "/var/lib/buildkite-agent/zephyr-module-cache:/var/lib/buildkite-agent/zephyr-module-cache"
- "/var/lib/buildkite-agent/zephyr-ccache:/root/.ccache"
workdir: "/workdir/zephyr"
agents:
- "queue=default"
- wait: ~
continue_on_failure: true
- plugins:
- junit-annotate#v1.7.0:
artifacts: sanitycheck-*.xml

50
.buildkite/run.sh Executable file
View File

@@ -0,0 +1,50 @@
#!/bin/bash
# Copyright (c) 2020 Linaro Limited
#
# SPDX-License-Identifier: Apache-2.0
echo "--- run $0"
git log -n 5 --oneline --decorate --abbrev=12
# Setup module cache
cd /workdir
ln -s /var/lib/buildkite-agent/zephyr-module-cache/modules
ln -s /var/lib/buildkite-agent/zephyr-module-cache/tools
ln -s /var/lib/buildkite-agent/zephyr-module-cache/bootloader
cd /workdir/zephyr
export JOB_NUM=$((${BUILDKITE_PARALLEL_JOB}+1))
# ccache stats
echo ""
echo "--- ccache stats at start"
ccache -s
if [ -n "${BUILDKITE_PULL_REQUEST_BASE_BRANCH}" ]; then
./scripts/ci/run_ci.sh -c -b ${BUILDKITE_PULL_REQUEST_BASE_BRANCH} -r origin \
-m ${JOB_NUM} -M ${BUILDKITE_PARALLEL_JOB_COUNT} -p ${BUILDKITE_PULL_REQUEST}
else
./scripts/ci/run_ci.sh -c -b ${BUILDKITE_BRANCH} -r origin \
-m ${JOB_NUM} -M ${BUILDKITE_PARALLEL_JOB_COUNT};
fi;
SANITY_EXIT_STATUS=$?
# Rename sanitycheck junit xml for use with junit-annotate-buildkite-plugin
# create dummy file if sanitycheck did nothing
if [ ! -f sanity-out/sanitycheck.xml ]; then
touch sanity-out/sanitycheck.xml
fi
mv sanity-out/sanitycheck.xml sanitycheck-${BUILDKITE_JOB_ID}.xml
buildkite-agent artifact upload sanitycheck-${BUILDKITE_JOB_ID}.xml
# ccache stats
echo "--- ccache stats at finish"
ccache -s
# disk usage
echo "--- disk usage at finish"
df -h
exit ${SANITY_EXIT_STATUS}

114
.github/workflows/compliance.yml vendored Normal file
View File

@@ -0,0 +1,114 @@
name: Compliance
on: pull_request
jobs:
compliance_job:
runs-on: ubuntu-latest
name: Run compliance checks on patch series (PR)
steps:
- name: Checkout the code
uses: actions/checkout@v1
- name: cache-pip
uses: actions/cache@v1
with:
path: ~/.cache/pip
key: ${{ runner.os }}-doc-pip
- name: Install python dependencies
run: |
pip3 install setuptools
pip3 install wheel
pip3 install python-magic junitparser gitlint pylint pykwalify
pip3 install west
- name: Run Compliance Tests
id: compliance
env:
BASE_REF: ${{ github.base_ref }}
run: |
export PATH=$PATH:~/.local/bin
export ZEPHYR_BASE=$PWD
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
git rebase origin/${BASE_REF}
./scripts/ci/check_compliance.py -m Codeowners -m Devicetree -m Gitlint -m Identity -m Nits -m pylint -m checkpatch -m Kconfig -c origin/${BASE_REF}.. || true
- name: upload-results
uses: actions/upload-artifact@master
continue-on-error: True
with:
name: compliance.xml
path: compliance.xml
- name: check-warns
run: |
if [ -s Nits.txt ]; then
errors=$(cat Nits.txt)
errors="${errors//'%'/'%25'}"
errors="${errors//$'\n'/'%0A'}"
errors="${errors//$'\r'/'%0D'}"
echo "::error file=Nits.txt::$errors"
exit=1
fi
if [ -s checkpatch.txt ]; then
errors=$(cat checkpatch.txt)
errors="${errors//'%'/'%25'}"
errors="${errors//$'\n'/'%0A'}"
errors="${errors//$'\r'/'%0D'}"
echo "::error file=Checkpatch.txt::$errors"
exit=1
fi
if [ -s Identity.txt ]; then
errors=$(cat Identity.txt)
errors="${errors//'%'/'%25'}"
errors="${errors//$'\n'/'%0A'}"
errors="${errors//$'\r'/'%0D'}"
echo "::error file=Identity.txt::$errors"
exit=1
fi
if [ -s Gitlint.txt ]; then
errors=$(cat Gitlint.txt)
errors="${errors//'%'/'%25'}"
errors="${errors//$'\n'/'%0A'}"
errors="${errors//$'\r'/'%0D'}"
echo "::error file=Gitlint.txt::$errors"
exit=1
fi
if [ -s pylint.txt ]; then
errors=$(cat pylint.txt)
errors="${errors//'%'/'%25'}"
errors="${errors//$'\n'/'%0A'}"
errors="${errors//$'\r'/'%0D'}"
echo "::error file=pylint.txt::$errors"
exit=1
fi
if [ -s Devicetree.txt ]; then
errors=$(cat Devicetree.txt)
errors="${errors//'%'/'%25'}"
errors="${errors//$'\n'/'%0A'}"
errors="${errors//$'\r'/'%0D'}"
echo "::error file=Devicetree.txt::$errors"
exit=1
fi
if [ -s Kconfig.txt ]; then
errors=$(cat Kconfig.txt)
errors="${errors//'%'/'%25'}"
errors="${errors//$'\n'/'%0A'}"
errors="${errors//$'\r'/'%0D'}"
echo "::error file=Kconfig.txt::$errors"
exit=1
fi
if [ -s Codeowners.txt ]; then
errors=$(cat Codeowners.txt)
errors="${errors//'%'/'%25'}"
errors="${errors//$'\n'/'%0A'}"
errors="${errors//$'\r'/'%0D'}"
echo "::error file=Codeowners.txt::$errors"
exit=1
fi
if [ ${exit} == 1 ]; then
exit 1;
fi

View File

@@ -16,6 +16,7 @@
/.known-issues/ @nashif
/.github/ @nashif
/.github/workflows/ @galak @nashif
/.buildkite/ @galak
/arch/arc/ @vonhust @ruuddw
/arch/arm/ @MaureenHelm @galak @ioannisg
/arch/arm/core/aarch32/cortex_m/cmse/ @ioannisg

View File

@@ -14,5 +14,8 @@ if(CONFIG_WIFI_ESWIFI)
eswifi_offload.c
eswifi_socket.c
)
zephyr_sources_ifdef(CONFIG_WIFI_ESWIFI_SHELL eswifi_shell.c)
zephyr_sources_ifdef(CONFIG_NET_SOCKETS_OFFLOAD eswifi_socket_offload.c)
endif()

View File

@@ -22,4 +22,10 @@ config WIFI_ESWIFI_THREAD_PRIO
This option sets the priority of the esWiFi threads.
Do not touch it unless you know what you are doing.
config WIFI_ESWIFI_SHELL
bool "esWiFi shell"
depends on SHELL
help
Enable esWiFi shell
endif

View File

@@ -144,4 +144,10 @@ int __eswifi_bind(struct eswifi_dev *eswifi, struct eswifi_off_socket *socket,
int eswifi_socket_offload_init(struct eswifi_dev *leswifi);
#endif
#if defined(CONFIG_WIFI_ESWIFI_SHELL)
void eswifi_shell_register(struct eswifi_dev *dev);
#else
#define eswifi_shell_register(dev)
#endif
#endif

View File

@@ -53,29 +53,30 @@ static int eswifi_reset(struct eswifi_dev *eswifi)
static inline int __parse_ssid(char *str, char *ssid)
{
/* fnt => '"SSID"' */
int i = 0;
if (!*str || (*str != '"')) {
return -EINVAL;
}
str++;
while (*str && (*str != '"')) {
*ssid++ = *str++;
}
*ssid = '\0';
/* fmt => "SSID" */
if (*str != '"') {
return -EINVAL;
return 0;
}
str++;
while (*str && (*str != '"') && i < WIFI_SSID_MAX_LEN) {
ssid[i++] = *str++;
}
return -EINVAL;
if (*str != '"') {
return 0;
}
return i;
}
static void __parse_scan_res(char *str, struct wifi_scan_result *res)
{
int field = 0;
int ret;
/* fmt => #001,"SSID",MACADDR,RSSI,BITRATE,MODE,SECURITY,BAND,CHANNEL */
@@ -91,8 +92,7 @@ static void __parse_scan_res(char *str, struct wifi_scan_result *res)
switch (++field) {
case 1: /* SSID */
__parse_ssid(str, res->ssid);
res->ssid_length = strlen(res->ssid);
res->ssid_length = __parse_ssid(str, res->ssid);
str += res->ssid_length;
break;
case 2: /* mac addr */
@@ -181,7 +181,7 @@ static int __parse_ipv4_address(char *str, char *ssid, u8_t ip[4])
unsigned int byte = -1;
/* fmt => [JOIN ] SSID,192.168.2.18,0,0 */
while (*str) {
while (*str && byte < 4) {
if (byte == -1) {
if (!strncmp(str, ssid, strlen(ssid))) {
byte = 0U;
@@ -244,8 +244,8 @@ static int eswifi_connect(struct eswifi_dev *eswifi)
char *rsp;
int err;
LOG_DBG("Connecting to %s (pass=%s)", eswifi->sta.ssid,
eswifi->sta.pass);
LOG_DBG("Connecting to %s (pass=%s)", log_strdup(eswifi->sta.ssid),
log_strdup(eswifi->sta.pass));
eswifi_lock(eswifi);
@@ -672,6 +672,8 @@ static int eswifi_init(struct device *dev)
k_work_init(&eswifi->request_work, eswifi_request_work);
eswifi_shell_register(eswifi);
return 0;
}

View File

@@ -0,0 +1,61 @@
/**
* Copyright (c) 2020 Linaro
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <kernel.h>
#include <shell/shell.h>
#include "eswifi.h"
static struct eswifi_dev *eswifi;
void eswifi_shell_register(struct eswifi_dev *dev)
{
/* only one instance supported */
if (eswifi) {
return;
}
eswifi = dev;
}
static int eswifi_shell_atcmd(const struct shell *shell, size_t argc,
char **argv)
{
int i;
if (eswifi == NULL) {
shell_print(shell, "no eswifi device registered");
return -ENOEXEC;
}
if (argc < 2) {
shell_help(shell);
return -ENOEXEC;
}
eswifi_lock(eswifi);
memset(eswifi->buf, 0, sizeof(eswifi->buf));
for (i = 1; i < argc; i++) {
strcat(eswifi->buf, argv[i]);
}
strcat(eswifi->buf, "\r");
shell_print(shell, "> %s", eswifi->buf);
eswifi_at_cmd(eswifi, eswifi->buf);
shell_print(shell, "< %s", eswifi->buf);
eswifi_unlock(eswifi);
return 0;
}
SHELL_STATIC_SUBCMD_SET_CREATE(eswifi_shell,
SHELL_CMD(atcmd, NULL, "<atcmd>", eswifi_shell_atcmd),
SHELL_SUBCMD_SET_END /* Array terminated. */
);
SHELL_CMD_REGISTER(eswifi, &eswifi_shell, "esWiFi debug shell", NULL);

View File

@@ -160,6 +160,10 @@ int __eswifi_off_start_client(struct eswifi_dev *eswifi,
__select_socket(eswifi, socket->index);
/* Stop any running client */
snprintk(eswifi->buf, sizeof(eswifi->buf), "P6=0\r");
eswifi_at_cmd(eswifi, eswifi->buf);
/* Set Remote IP */
snprintk(eswifi->buf, sizeof(eswifi->buf), "P3=%u.%u.%u.%u\r",
sin_addr->s4_addr[0], sin_addr->s4_addr[1],

View File

@@ -13,9 +13,16 @@ extern "C" {
#if defined(CONFIG_FILE_SYSTEM_LITTLEFS)
#define MAX_FILE_NAME 256
#else /* FAT_FS */
#elif defined(CONFIG_FAT_FILESYSTEM_ELM)
#if defined(CONFIG_FS_FATFS_LFN)
#define MAX_FILE_NAME CONFIG_FS_FATFS_MAX_LFN
#else /* CONFIG_FS_FATFS_LFN */
#define MAX_FILE_NAME 12 /* Uses 8.3 SFN */
#endif
#endif /* CONFIG_FS_FATFS_LFN */
#else /* filesystem selection */
/* Use standard 8.3 when no filesystem is explicitly selected */
#define MAX_FILE_NAME 12
#endif /* filesystem selection */
struct fs_mount_t;

View File

@@ -147,6 +147,11 @@ enum coap_response_code {
#define COAP_CODE_EMPTY (0)
/* block option helper */
#define GET_BLOCK_NUM(v) ((v) >> 4)
#define GET_BLOCK_SIZE(v) (((v) & 0x7))
#define GET_MORE(v) (!!((v) & 0x08))
struct coap_observer;
struct coap_packet;
struct coap_pending;
@@ -564,6 +569,17 @@ int coap_append_size1_option(struct coap_packet *cpkt,
int coap_append_size2_option(struct coap_packet *cpkt,
struct coap_block_context *ctx);
/**
* @brief Get the integer representation of a CoAP option.
*
* @param cpkt Packet to be inspected
* @param code CoAP option code
*
* @return Integer value >= 0 in case of success or negative in case
* of error.
*/
int coap_get_option_int(const struct coap_packet *cpkt, u16_t code);
/**
* @brief Retrieves BLOCK{1,2} and SIZE{1,2} from @a cpkt and updates
* @a ctx accordingly.

View File

@@ -9,4 +9,5 @@ zephyr_library()
zephyr_library_sources_ifdef(CONFIG_UPDATEHUB updatehub.c)
zephyr_library_sources_ifdef(CONFIG_UPDATEHUB updatehub_device.c)
zephyr_library_sources_ifdef(CONFIG_UPDATEHUB updatehub_firmware.c)
zephyr_library_sources_ifdef(CONFIG_UPDATEHUB updatehub_timer.c)
zephyr_library_sources_ifdef(CONFIG_UPDATEHUB_SHELL shell.c)

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2018, 2019 O.S.Systems
# Copyright (c) 2018-2020 O.S.Systems
# SPDX -License-Identifier: Apache-2.0
menuconfig UPDATEHUB
@@ -86,6 +86,40 @@ config UPDATEHUB_DTLS
Enables DTLS communication between the UpdateHub
client and the server
config UPDATEHUB_COAP_CONN_TIMEOUT
int "CoAP connection timeout in seconds"
default 10
range 1 360
depends on UPDATEHUB
help
Set the CoAP connection timeout value.
config UPDATEHUB_COAP_MAX_RETRY
int "Maximum retries attempts to download a packet"
default 10
range 3 10
depends on UPDATEHUB
help
Set the maximum number of retries attempts to download a packet
before abort a current update.
config UPDATEHUB_COAP_BLOCK_SIZE_EXP
int "Max CoAP block size defined as 2^(4 + EXP)"
default 6
range 0 6
depends on UPDATEHUB
help
Configure the max size of a data payload were value:
0 - COAP_BLOCK_16
1 - COAP_BLOCK_32
2 - COAP_BLOCK_64
3 - COAP_BLOCK_128
4 - COAP_BLOCK_256
5 - COAP_BLOCK_512
6 - COAP_BLOCK_1024
This value is mapped directly to enum coap_block_size.
module = UPDATEHUB
module-str = Log level for UpdateHub
module-help = Enables logging for UpdateHub code.

View File

@@ -5,8 +5,7 @@
*/
#include <logging/log.h>
LOG_MODULE_REGISTER(updatehub);
LOG_MODULE_REGISTER(updatehub, CONFIG_UPDATEHUB_LOG_LEVEL);
#include <zephyr.h>
@@ -27,6 +26,7 @@ LOG_MODULE_REGISTER(updatehub);
#include "updatehub_priv.h"
#include "updatehub_firmware.h"
#include "updatehub_device.h"
#include "updatehub_timer.h"
#if defined(CONFIG_UPDATEHUB_DTLS)
#define CA_CERTIFICATE_TAG 1
@@ -43,7 +43,6 @@ LOG_MODULE_REGISTER(updatehub);
* 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)
@@ -147,6 +146,22 @@ is_compatible_hardware(struct resp_probe_some_boards *metadata_some_boards)
return false;
}
static void cleanup_connection(void)
{
int i;
if (close(ctx.sock) < 0) {
LOG_ERR("Could not close the socket");
}
for (i = 0; i < ctx.nfds; i++) {
memset(&ctx.fds[i], 0, sizeof(ctx.fds[i]));
}
ctx.nfds = 0;
ctx.sock = 0;
}
static bool start_coap_client(void)
{
struct addrinfo *addr;
@@ -154,6 +169,8 @@ static bool start_coap_client(void)
int resolve_attempts = 10;
int ret = -1;
memset(&hints, 0, sizeof(hints));
if (IS_ENABLED(CONFIG_NET_IPV6)) {
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_STREAM;
@@ -184,44 +201,45 @@ static bool start_coap_client(void)
return false;
}
ret = 1;
ctx.sock = socket(addr->ai_family, SOCK_DGRAM, protocol);
if (ctx.sock < 0) {
LOG_ERR("Failed to create UDP socket");
return false;
goto error;
}
ret = -1;
#if defined(CONFIG_UPDATEHUB_DTLS)
if (setsockopt(ctx.sock, SOL_TLS, TLS_SEC_TAG_LIST,
sec_list, sizeof(sec_list)) < 0) {
LOG_ERR("Failed to set TLS_TAG option");
return false;
goto error;
}
if (setsockopt(ctx.sock, SOL_TLS, TLS_PEER_VERIFY, &verify, sizeof(int)) < 0) {
LOG_ERR("Failed to set TLS_PEER_VERIFY option");
return false;
goto error;
}
#endif
if (connect(ctx.sock, addr->ai_addr, addr->ai_addrlen) < 0) {
LOG_ERR("Cannot connect to UDP remote");
return false;
goto error;
}
prepare_fds();
return true;
}
ret = 0;
error:
freeaddrinfo(addr);
static void cleanup_connection(void)
{
if (close(ctx.sock) < 0) {
LOG_ERR("Could not close the socket");
if (ret > 0) {
cleanup_connection();
}
memset(&ctx.fds[1], 0, sizeof(ctx.fds[1]));
ctx.nfds = 0;
ctx.sock = 0;
return (ret == 0) ? true : false;
}
static int send_request(enum coap_msgtype msgtype, enum coap_method method,
@@ -363,6 +381,29 @@ static bool install_update_cb_sha256(void)
return true;
}
static int install_update_cb_check_blk_num(struct coap_packet *resp)
{
int blk_num;
int blk2_opt;
blk2_opt = coap_get_option_int(resp, COAP_OPTION_BLOCK2);
if ((resp->max_len - resp->offset) <= 0 || (blk2_opt < 0)) {
LOG_DBG("Invalid data received or block number is < 0");
return -ENOENT;
}
blk_num = GET_BLOCK_NUM(blk2_opt);
if (blk_num == updatehub_blk_get(UPDATEHUB_BLK_INDEX)) {
updatehub_blk_inc(UPDATEHUB_BLK_INDEX);
return 0;
}
return -EAGAIN;
}
static void install_update_cb(void)
{
struct coap_packet response_packet;
@@ -390,6 +431,15 @@ static void install_update_cb(void)
goto cleanup;
}
if (install_update_cb_check_blk_num(&response_packet) < 0) {
ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR;
goto cleanup;
}
updatehub_tmr_stop();
updatehub_blk_set(UPDATEHUB_BLK_ATTEMPT, 0);
updatehub_blk_set(UPDATEHUB_BLK_TX_AVAILABLE, 1);
ctx.downloaded_size = ctx.downloaded_size +
(response_packet.max_len - response_packet.offset);
@@ -438,9 +488,6 @@ cleanup:
static enum updatehub_response install_update(void)
{
int verification_download = 0;
int attempts_download = 0;
if (boot_erase_img_bank(FLASH_AREA_ID(image_1)) != 0) {
LOG_ERR("Failed to init flash and erase second slot");
ctx.code_status = UPDATEHUB_FLASH_INIT_ERROR;
@@ -458,39 +505,57 @@ static enum updatehub_response install_update(void)
goto error;
}
if (coap_block_transfer_init(&ctx.block, COAP_BLOCK_1024,
if (coap_block_transfer_init(&ctx.block,
CONFIG_UPDATEHUB_COAP_BLOCK_SIZE_EXP,
update_info.image_size) < 0) {
LOG_ERR("Unable init block transfer");
ctx.code_status = UPDATEHUB_NETWORKING_ERROR;
goto cleanup;
}
flash_img_init(&ctx.flash_ctx);
if (flash_img_init(&ctx.flash_ctx)) {
LOG_ERR("Unable init flash");
ctx.code_status = UPDATEHUB_FLASH_INIT_ERROR;
goto cleanup;
}
ctx.downloaded_size = 0;
updatehub_blk_set(UPDATEHUB_BLK_ATTEMPT, 0);
updatehub_blk_set(UPDATEHUB_BLK_INDEX, 0);
updatehub_blk_set(UPDATEHUB_BLK_TX_AVAILABLE, 1);
while (ctx.downloaded_size != ctx.block.total_size) {
verification_download = ctx.downloaded_size;
if (updatehub_blk_get(UPDATEHUB_BLK_TX_AVAILABLE)) {
if (send_request(COAP_TYPE_CON, COAP_METHOD_GET,
UPDATEHUB_DOWNLOAD) < 0) {
ctx.code_status = UPDATEHUB_NETWORKING_ERROR;
goto cleanup;
}
if (send_request(COAP_TYPE_CON, COAP_METHOD_GET,
UPDATEHUB_DOWNLOAD) < 0) {
ctx.code_status = UPDATEHUB_NETWORKING_ERROR;
goto cleanup;
updatehub_blk_set(UPDATEHUB_BLK_TX_AVAILABLE, 0);
updatehub_blk_inc(UPDATEHUB_BLK_ATTEMPT);
updatehub_tmr_start();
}
install_update_cb();
if (ctx.code_status != UPDATEHUB_OK) {
if (ctx.code_status == UPDATEHUB_OK) {
continue;
}
if (ctx.code_status != UPDATEHUB_DOWNLOAD_ERROR &&
ctx.code_status != UPDATEHUB_NETWORKING_ERROR) {
LOG_DBG("status: %d", ctx.code_status);
goto cleanup;
}
if (verification_download == ctx.downloaded_size) {
if (attempts_download == COAP_MAX_RETRY) {
LOG_ERR("Could not get the packet");
ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR;
goto cleanup;
}
attempts_download++;
if (updatehub_blk_get(UPDATEHUB_BLK_ATTEMPT) ==
CONFIG_UPDATEHUB_COAP_MAX_RETRY) {
updatehub_tmr_stop();
LOG_ERR("Could not get the packet");
ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR;
goto cleanup;
}
}
@@ -623,6 +688,7 @@ static void probe_cb(char *metadata, size_t metadata_size)
return;
}
memset(metadata, 0, metadata_size);
memcpy(metadata, reply.data + reply.offset,
reply.max_len - reply.offset);
@@ -644,8 +710,8 @@ static void probe_cb(char *metadata, size_t metadata_size)
enum updatehub_response updatehub_probe(void)
{
struct probe request;
struct resp_probe_some_boards metadata_some_boards;
struct resp_probe_any_boards metadata_any_boards;
struct resp_probe_some_boards metadata_some_boards = { 0 };
struct resp_probe_any_boards metadata_any_boards = { 0 };
char *metadata = k_malloc(MAX_DOWNLOAD_DATA);
char *metadata_copy = k_malloc(MAX_DOWNLOAD_DATA);
@@ -693,6 +759,8 @@ enum updatehub_response updatehub_probe(void)
goto error;
}
ctx.nfds = 0;
if (!start_coap_client()) {
ctx.code_status = UPDATEHUB_NETWORKING_ERROR;
goto error;
@@ -716,6 +784,9 @@ enum updatehub_response updatehub_probe(void)
goto cleanup;
}
LOG_DBG("metadata size: %d", strlen(metadata));
LOG_HEXDUMP_DBG(metadata, MAX_DOWNLOAD_DATA, "metadata");
memcpy(metadata_copy, metadata, strlen(metadata));
if (json_obj_parse(metadata, strlen(metadata),
recv_probe_sh_array_descr,
@@ -731,6 +802,12 @@ enum updatehub_response updatehub_probe(void)
goto cleanup;
}
if (metadata_any_boards.objects_len != 2) {
LOG_ERR("Could not parse json");
ctx.code_status = UPDATEHUB_METADATA_ERROR;
goto cleanup;
}
sha256size = strlen(
metadata_any_boards.objects[1].objects.sha256sum) + 1;
@@ -744,7 +821,14 @@ enum updatehub_response updatehub_probe(void)
metadata_any_boards.objects[1].objects.sha256sum,
SHA256_HEX_DIGEST_SIZE);
update_info.image_size = metadata_any_boards.objects[1].objects.size;
LOG_DBG("metadata_any: %s", update_info.sha256sum_image);
} else {
if (metadata_some_boards.objects_len != 2) {
LOG_ERR("Could not parse json");
ctx.code_status = UPDATEHUB_METADATA_ERROR;
goto cleanup;
}
if (!is_compatible_hardware(&metadata_some_boards)) {
LOG_ERR("Incompatible hardware");
ctx.code_status =
@@ -766,6 +850,7 @@ enum updatehub_response updatehub_probe(void)
SHA256_HEX_DIGEST_SIZE);
update_info.image_size =
metadata_some_boards.objects[1].objects.size;
LOG_DBG("metadata_some: %s", update_info.sha256sum_image);
}
ctx.code_status = UPDATEHUB_HAS_UPDATE;

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 2020 O.S.Systems
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <logging/log.h>
LOG_MODULE_DECLARE(updatehub, CONFIG_UPDATEHUB_LOG_LEVEL);
#include <zephyr.h>
#include "updatehub_timer.h"
static int blk_vars[UPDATEHUB_BLK_MAX_VARS];
static void timer_expire(struct k_timer *timer)
{
LOG_DBG("tmr_expire");
blk_vars[UPDATEHUB_BLK_TX_AVAILABLE] = 1;
}
K_TIMER_DEFINE(uhu_packet_down_tmr, timer_expire, NULL);
int updatehub_blk_get(enum updatehub_blk_vars var)
{
LOG_DBG("blk_get[%d] = %d", var, blk_vars[var]);
return blk_vars[var];
}
void updatehub_blk_inc(enum updatehub_blk_vars var)
{
blk_vars[var]++;
LOG_DBG("blk_inc[%d] = %d", var, blk_vars[var]);
}
void updatehub_blk_set(enum updatehub_blk_vars var, int val)
{
LOG_DBG("blk_set[%d] = %d", var, val);
blk_vars[var] = val;
}
void updatehub_tmr_start(void)
{
LOG_DBG("tmr_start");
k_timer_start(&uhu_packet_down_tmr,
K_SECONDS(CONFIG_UPDATEHUB_COAP_CONN_TIMEOUT),
K_NO_WAIT);
}
void updatehub_tmr_stop(void)
{
LOG_DBG("tmr_stop");
k_timer_stop(&uhu_packet_down_tmr);
}

View File

@@ -0,0 +1,25 @@
/*
* Copyright (c) 2020 O.S.Systems
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __UPDATEHUB_TIMER_H__
#define __UPDATEHUB_TIMER_H__
enum updatehub_blk_vars {
UPDATEHUB_BLK_ATTEMPT,
UPDATEHUB_BLK_INDEX,
UPDATEHUB_BLK_TX_AVAILABLE,
UPDATEHUB_BLK_MAX_VARS,
};
int updatehub_blk_get(enum updatehub_blk_vars var);
void updatehub_blk_inc(enum updatehub_blk_vars var);
void updatehub_blk_set(enum updatehub_blk_vars var, int val);
void updatehub_tmr_start(void);
void updatehub_tmr_stop(void);
#endif /* __UPDATEHUB_TIMER_H__ */

View File

@@ -39,11 +39,6 @@ LOG_MODULE_REGISTER(net_coap_server_sample, LOG_LEVEL_DBG);
#define NUM_PENDINGS 3
/* block option helper */
#define GET_BLOCK_NUM(v) ((v) >> 4)
#define GET_BLOCK_SIZE(v) (((v) & 0x7))
#define GET_MORE(v) (!!((v) & 0x08))
/* CoAP socket fd */
static int sock;
@@ -780,19 +775,6 @@ end:
return r;
}
static int get_option_int(const struct coap_packet *pkt, u8_t opt)
{
struct coap_option option;
int r;
r = coap_find_options(pkt, opt, &option, 1);
if (r <= 0) {
return -ENOENT;
}
return coap_option_value_to_int(&option);
}
static int large_update_put(struct coap_resource *resource,
struct coap_packet *request,
struct sockaddr *addr, socklen_t addr_len)
@@ -810,7 +792,7 @@ static int large_update_put(struct coap_resource *resource,
int r;
bool last_block;
r = get_option_int(request, COAP_OPTION_BLOCK1);
r = coap_get_option_int(request, COAP_OPTION_BLOCK1);
if (r < 0) {
return -EINVAL;
}
@@ -899,7 +881,7 @@ static int large_create_post(struct coap_resource *resource,
int r;
bool last_block;
r = get_option_int(request, COAP_OPTION_BLOCK1);
r = coap_get_option_int(request, COAP_OPTION_BLOCK1);
if (r < 0) {
return -EINVAL;
}

View File

@@ -14,6 +14,7 @@ CONFIG_NET_DHCPV4=y
#Optional if you would like test on the your server
CONFIG_SHELL=y
CONFIG_UPDATEHUB_SHELL=y
CONFIG_SHELL_STACK_SIZE=6144
# Debug helpers
CONFIG_LOG=y

1123
scripts/ci/check_compliance.py Executable file

File diff suppressed because it is too large Load Diff

249
scripts/ci/pylintrc Normal file
View File

@@ -0,0 +1,249 @@
# Copyright (c) 2019, Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
# pylint configuration for the PyLint check in check_compliance.py.
#
# To run pylint manually with this configuration from the Zephyr repo, do
#
# pylint3 --rcfile=ci-tools/scripts/pylintrc <Python file>
#
# This command will check all scripts:
#
# pylint3 --rcfile=ci-tools/scripts/pylintrc $(git ls-files '*.py')
[MASTER]
# Use multiple processes
jobs=0
# Do not pickle collected data for comparisons
persistent=no
[REPORTS]
# Only show messages, not full report
reports=no
# Disable score
score=no
[MESSAGES CONTROL]
# Only enable specific (hopefully) uncontroversial warnings. Use
# 'pylint3 --list-msgs' to list messages and their IDs.
#
# These might be nice to check too, but currently trigger false positives:
#
# no-member
# arguments-differ
# redefine-in-handler
# abstract-method
#
# These might be too controversial:
#
# no-else-return
# consider-using-get
# redefined-builtin
#
# These tell you to use logger.warning("foo %d bar", 3) instead of e.g.
# logger.warning("foo {} bar".format(3)), but it's not a clear win in all
# cases. f-strings would be nicer too, and it's easier to convert from format()
# to those.
#
# logging-not-lazy
# logging-format-interpolation
# logging-fstring-interpolation
disable=all
# Identifiers are in the same order as in 'pylint3 --list-msgs'. Entire
# message "types" (~= severities) like F(atal), E(error),... are listed
# first.
enable=
F, # atal
empty-docstring,
unneeded-not,
singleton-comparison,
misplaced-comparison-constant,
unidiomatic-typecheck,
consider-using-enumerate,
consider-iterating-dictionary,
bad-classmethod-argument,
bad-mcs-method-argument,
bad-mcs-classmethod-argument,
single-string-used-for-slots,
trailing-newlines,
trailing-whitespace,
missing-final-newline,
superfluous-parens,
mixed-line-endings,
unexpected-line-ending-format,
invalid-characters-in-docstring,
useless-import-alias,
len-as-condition,
syntax-error,
init-is-generator,
return-in-init,
function-redefined,
not-in-loop,
return-outside-function,
yield-outside-function,
nonexistent-operator,
duplicate-argument-name,
abstract-class-instantiated,
bad-reversed-sequence,
too-many-star-expressions,
invalid-star-assignment-target,
star-needs-assignment-target,
nonlocal-and-global,
continue-in-finally,
nonlocal-without-binding,
misplaced-format-function,
method-hidden,
access-member-before-definition,
no-method-argument,
no-self-argument,
invalid-slots-object,
assigning-non-slot,
invalid-slots,
inherit-non-class,
inconsistent-mro,
duplicate-bases,
non-iterator-returned,
unexpected-special-method-signature,
invalid-length-returned,
relative-beyond-top-level,
used-before-assignment,
undefined-variable,
undefined-all-variable,
invalid-all-object,
no-name-in-module,
unpacking-non-sequence,
bad-except-order,
raising-bad-type,
bad-exception-context,
misplaced-bare-raise,
raising-non-exception,
notimplemented-raised,
catching-non-exception,
bad-super-call,
not-callable,
assignment-from-no-return,
no-value-for-parameter,
too-many-function-args,
unexpected-keyword-arg,
redundant-keyword-arg,
missing-kwoa,
invalid-sequence-index,
invalid-slice-index,
assignment-from-none,
not-context-manager,
invalid-unary-operand-type,
unsupported-binary-operation,
repeated-keyword,
not-an-iterable,
not-a-mapping,
unsupported-membership-test,
unsubscriptable-object,
unsupported-assignment-operation,
unsupported-delete-operation,
invalid-metaclass,
unhashable-dict-key,
logging-unsupported-format,
logging-format-truncated,
logging-too-many-args,
logging-too-few-args,
bad-format-character,
truncated-format-string,
mixed-format-string,
format-needs-mapping,
missing-format-string-key,
too-many-format-args,
too-few-format-args,
bad-string-format-type,
bad-str-strip-call,
invalid-envvar-value,
yield-inside-async-function,
not-async-context-manager,
useless-suppression,
deprecated-pragma,
use-symbolic-message-instead,
literal-comparison,
comparison-with-itself,
no-self-use,
no-classmethod-decorator,
no-staticmethod-decorator,
cyclic-import,
duplicate-code,
consider-merging-isinstance,
simplifiable-if-statement,
redefined-argument-from-local,
trailing-comma-tuple,
stop-iteration-return,
useless-return,
consider-swap-variables,
consider-using-join,
consider-using-in,
chained-comparison,
consider-using-dict-comprehension,
consider-using-set-comprehension,
simplifiable-if-expression,
unreachable,
pointless-statement,
pointless-string-statement,
expression-not-assigned,
unnecessary-pass,
unnecessary-lambda,
duplicate-key,
assign-to-new-keyword,
useless-else-on-loop,
confusing-with-statement,
using-constant-test,
comparison-with-callable,
lost-exception,
assert-on-tuple,
bad-staticmethod-argument,
super-init-not-called,
non-parent-init-called,
useless-super-delegation,
unnecessary-semicolon,
bad-indentation,
mixed-indentation,
deprecated-module,
reimported,
import-self,
misplaced-future,
global-variable-not-assigned,
unused-import,
unused-variable,
undefined-loop-variable,
unbalanced-tuple-unpacking,
possibly-unused-variable,
self-cls-assignment,
bare-except,
duplicate-except,
try-except-raise,
binary-op-exception,
raising-format-tuple,
wrong-exception-operation,
keyword-arg-before-vararg,
bad-format-string-key,
unused-format-string-key,
bad-format-string,
unused-format-string-argument,
format-combined-specification,
missing-format-attribute,
invalid-format-index,
anomalous-backslash-in-string,
anomalous-unicode-escape-in-string,
bad-open-mode,
redundant-unittest-assert,
deprecated-method,
bad-thread-instantiation,
shallow-copy-environ,
invalid-envvar-default,
deprecated-string-function,
deprecated-str-translate-call,
deprecated-itertools-function,
deprecated-types-field,

View File

@@ -146,7 +146,8 @@ function west_setup() {
pushd ..
if [ ! -d .west ]; then
west init -l ${git_dir}
west update
west update 1> west.update.log
west forall -c 'git reset --hard HEAD'
fi
popd
}
@@ -268,6 +269,8 @@ if [ -n "$main_ci" ]; then
tail -n +2 test_file_1.txt > test_file_1_in.txt
cat test_file_3.txt test_file_2_in.txt test_file_1_in.txt > test_file.txt
echo "+++ run sanitycheck"
# Run a subset of tests based on matrix size
${sanitycheck} ${sanitycheck_options} --load-tests test_file.txt \
--subset ${matrix}/${matrix_builds} --retry-failed 3

View File

@@ -26,3 +26,6 @@ doc/*
scripts/ci/sanitycheck_ignore.txt
scripts/ci/what_changed.py
scripts/requirements*
.github/workflows/compliance.yml
scripts/ci/check_compliance.py
scripts/ci/pylintrc

View File

@@ -5873,10 +5873,14 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
goto ull_conn_rx_unknown_rsp_send;
}
struct pdu_data_llctrl *llctrl = (void *)&pdu_rx->llctrl;
if (0) {
#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
} else if (conn->llcp_conn_param.ack !=
conn->llcp_conn_param.req) {
} else if ((conn->llcp_conn_param.ack !=
conn->llcp_conn_param.req) &&
(llctrl->unknown_rsp.type ==
PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ)) {
struct lll_conn *lll = &conn->lll;
struct node_rx_cu *cu;
@@ -5938,7 +5942,9 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
#endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
} else if (conn->llcp_length.req != conn->llcp_length.ack) {
} else if ((conn->llcp_length.req != conn->llcp_length.ack) &&
(llctrl->unknown_rsp.type ==
PDU_DATA_LLCTRL_TYPE_LENGTH_REQ)) {
/* Mark length update as unsupported */
conn->llcp_length.disabled = 1U;
@@ -5951,8 +5957,9 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
#if defined(CONFIG_BT_CTLR_PHY)
} else if (conn->llcp_phy.req !=
conn->llcp_phy.ack) {
} else if ((conn->llcp_phy.req != conn->llcp_phy.ack) &&
(llctrl->unknown_rsp.type ==
PDU_DATA_LLCTRL_TYPE_PHY_REQ)) {
struct lll_conn *lll = &conn->lll;
/* Mark phy update as unsupported */
@@ -5983,9 +5990,6 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
#endif /* CONFIG_BT_CTLR_PHY */
} else {
struct pdu_data_llctrl *llctrl;
llctrl = (void *)&pdu_rx->llctrl;
switch (llctrl->unknown_rsp.type) {
#if defined(CONFIG_BT_CTLR_LE_PING)

View File

@@ -73,6 +73,7 @@ enum {
ATT_PENDING_CFM,
ATT_DISCONNECTED,
ATT_ENHANCED,
ATT_PENDING_SENT,
/* Total number of flags - must be at the end of the enum */
ATT_NUM_FLAGS,
@@ -85,6 +86,7 @@ struct bt_att_chan {
struct bt_l2cap_le_chan chan;
ATOMIC_DEFINE(flags, ATT_NUM_FLAGS);
struct bt_att_req *req;
struct k_fifo tx_queue;
struct k_delayed_work timeout_work;
struct k_sem tx_sem;
void (*sent)(struct bt_att_chan *chan);
@@ -128,6 +130,7 @@ static void att_req_destroy(struct bt_att_req *req)
typedef void (*bt_att_chan_sent_t)(struct bt_att_chan *chan);
static bt_att_chan_sent_t chan_cb(struct net_buf *buf);
static bt_conn_tx_cb_t att_cb(bt_att_chan_sent_t cb);
void att_sent(struct bt_conn *conn, void *user_data)
{
@@ -149,10 +152,17 @@ static int chan_send(struct bt_att_chan *chan, struct net_buf *buf,
BT_DBG("code 0x%02x", hdr->code);
chan->sent = cb ? cb : chan_cb(buf);
if (IS_ENABLED(CONFIG_BT_EATT) &&
atomic_test_bit(chan->flags, ATT_ENHANCED)) {
/* Check if sent is pending already, if it does it cannot be
* modified so the operation will need to be queued.
*/
if (atomic_test_and_set_bit(chan->flags, ATT_PENDING_SENT)) {
return -EAGAIN;
}
chan->sent = cb ? cb : chan_cb(buf);
if (hdr->code == BT_ATT_OP_SIGNED_WRITE_CMD) {
return -ENOTSUP;
}
@@ -178,15 +188,64 @@ static int chan_send(struct bt_att_chan *chan, struct net_buf *buf,
}
}
chan->sent = cb ? cb : chan_cb(buf);
return bt_l2cap_send_cb(chan->att->conn, BT_L2CAP_CID_ATT, buf,
att_sent, &chan->chan.chan);
att_cb(chan->sent), &chan->chan.chan);
}
static int process_queue(struct bt_att_chan *chan, struct k_fifo *queue)
{
struct net_buf *buf;
int err;
buf = net_buf_get(queue, K_NO_WAIT);
if (buf) {
err = chan_send(chan, buf, NULL);
if (err) {
/* Push it back if it could not be send */
k_queue_prepend(&queue->_queue, buf);
return err;
}
return 0;
}
return -ENOENT;
}
/* Send requests without taking tx_sem */
static int chan_req_send(struct bt_att_chan *chan, struct bt_att_req *req)
{
int err;
if (chan->chan.tx.mtu < net_buf_frags_len(req->buf)) {
return -EMSGSIZE;
}
BT_DBG("chan %p req %p len %zu", chan, req,
net_buf_frags_len(req->buf));
chan->req = req;
/* Save request state so it can be resent */
net_buf_simple_save(&req->buf->b, &req->state);
/* Keep a reference for resending in case of an error */
err = chan_send(chan, net_buf_ref(req->buf), NULL);
if (err < 0) {
net_buf_unref(req->buf);
chan->req = NULL;
}
return err;
}
static void bt_att_sent(struct bt_l2cap_chan *ch)
{
struct bt_att_chan *chan = ATT_CHAN(ch);
struct bt_att *att = chan->att;
struct net_buf *buf;
int err;
BT_DBG("chan %p", chan);
@@ -194,20 +253,33 @@ static void bt_att_sent(struct bt_l2cap_chan *ch)
chan->sent(chan);
}
while ((buf = net_buf_get(&att->tx_queue, K_NO_WAIT))) {
/* Check if the queued buf is a request */
if (chan->req && chan->req->buf == buf) {
/* Save request state so it can be resent */
net_buf_simple_save(&chan->req->buf->b,
&chan->req->state);
atomic_clear_bit(chan->flags, ATT_PENDING_SENT);
/* Process pending requests first since they require a response they
* can only be processed one at time while if other queues were
* processed before they may always contain a buffer starving the
* request queue.
*/
if (!chan->req && !sys_slist_is_empty(&att->reqs)) {
sys_snode_t *node = sys_slist_get(&att->reqs);
if (chan_req_send(chan, ATT_REQ(node)) >= 0) {
return;
}
if (chan_send(chan, buf, NULL) < 0) {
/* Push it back if it could not be send */
k_queue_prepend(&att->tx_queue._queue, buf);
break;
}
/* Prepend back to the list as it could not be sent */
sys_slist_prepend(&att->reqs, node);
}
/* Process channel queue */
err = process_queue(chan, &chan->tx_queue);
if (!err) {
return;
}
/* Process global queue */
err = process_queue(chan, &att->tx_queue);
if (!err) {
return;
}
@@ -257,6 +329,55 @@ static bt_att_chan_sent_t chan_cb(struct net_buf *buf)
}
}
static void att_cfm_sent(struct bt_conn *conn, void *user_data)
{
struct bt_l2cap_chan *ch = user_data;
struct bt_att_chan *chan = ATT_CHAN(ch);
BT_DBG("conn %p chan %p", conn, chan);
chan->sent = chan_cfm_sent;
att_sent(conn, user_data);
}
static void att_rsp_sent(struct bt_conn *conn, void *user_data)
{
struct bt_l2cap_chan *ch = user_data;
struct bt_att_chan *chan = ATT_CHAN(ch);
BT_DBG("conn %p chan %p", conn, chan);
chan->sent = chan_rsp_sent;
att_sent(conn, user_data);
}
static void att_req_sent(struct bt_conn *conn, void *user_data)
{
struct bt_l2cap_chan *ch = user_data;
struct bt_att_chan *chan = ATT_CHAN(ch);
BT_DBG("conn %p chan %p", conn, chan);
chan->sent = chan_req_sent;
att_sent(conn, user_data);
}
static bt_conn_tx_cb_t att_cb(bt_att_chan_sent_t cb)
{
if (cb == chan_rsp_sent) {
return att_rsp_sent;
} else if (cb == chan_cfm_sent) {
return att_cfm_sent;
} else if (cb == chan_req_sent) {
return att_req_sent;
} else {
return att_sent;
}
}
struct net_buf *bt_att_chan_create_pdu(struct bt_att_chan *chan, u8_t op,
size_t len)
{
@@ -316,6 +437,18 @@ static int bt_att_chan_send(struct bt_att_chan *chan, struct net_buf *buf,
return chan_send(chan, buf, cb);
}
static void bt_att_chan_send_rsp(struct bt_att_chan *chan, struct net_buf *buf,
bt_att_chan_sent_t cb)
{
int err;
err = bt_att_chan_send(chan, buf, cb);
if (err) {
/* Responses need to be sent back using the same channel */
net_buf_put(&chan->tx_queue, buf);
}
}
static void send_err_rsp(struct bt_att_chan *chan, u8_t req, u16_t handle,
u8_t err)
{
@@ -337,7 +470,7 @@ static void send_err_rsp(struct bt_att_chan *chan, u8_t req, u16_t handle,
rsp->handle = sys_cpu_to_le16(handle);
rsp->error = err;
(void)bt_att_chan_send(chan, buf, chan_rsp_sent);
bt_att_chan_send_rsp(chan, buf, chan_rsp_sent);
}
static u8_t att_mtu_req(struct bt_att_chan *chan, struct net_buf *buf)
@@ -378,7 +511,7 @@ static u8_t att_mtu_req(struct bt_att_chan *chan, struct net_buf *buf)
rsp = net_buf_add(pdu, sizeof(*rsp));
rsp->mtu = sys_cpu_to_le16(mtu_server);
(void)bt_att_chan_send(chan, pdu, chan_rsp_sent);
bt_att_chan_send_rsp(chan, pdu, chan_rsp_sent);
/* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part F] page 484:
*
@@ -404,29 +537,13 @@ static int bt_att_chan_req_send(struct bt_att_chan *chan,
BT_DBG("req %p", req);
if (chan->chan.tx.mtu < net_buf_frags_len(req->buf)) {
return -EMSGSIZE;
}
if (k_sem_take(&chan->tx_sem, K_NO_WAIT) < 0) {
return -EAGAIN;
}
BT_DBG("chan %p req %p len %zu", chan, req,
net_buf_frags_len(req->buf));
chan->req = req;
/* Save request state so it can be resent */
net_buf_simple_save(&req->buf->b, &req->state);
/* Keep a reference for resending in case of an error */
err = chan_send(chan, net_buf_ref(req->buf), NULL);
err = chan_req_send(chan, req);
if (err < 0) {
net_buf_unref(req->buf);
req->buf = NULL;
k_sem_give(&chan->tx_sem);
chan->req = NULL;
}
return err;
@@ -644,7 +761,7 @@ static u8_t att_find_info_rsp(struct bt_att_chan *chan, u16_t start_handle,
return 0;
}
(void)bt_att_chan_send(chan, data.buf, chan_rsp_sent);
bt_att_chan_send_rsp(chan, data.buf, chan_rsp_sent);
return 0;
}
@@ -807,7 +924,7 @@ static u8_t att_find_type_rsp(struct bt_att_chan *chan, u16_t start_handle,
return 0;
}
(void)bt_att_chan_send(chan, data.buf, chan_rsp_sent);
bt_att_chan_send_rsp(chan, data.buf, chan_rsp_sent);
return 0;
}
@@ -1038,7 +1155,7 @@ static u8_t att_read_type_rsp(struct bt_att_chan *chan, struct bt_uuid *uuid,
return 0;
}
(void)bt_att_chan_send(chan, data.buf, chan_rsp_sent);
bt_att_chan_send_rsp(chan, data.buf, chan_rsp_sent);
return 0;
}
@@ -1157,7 +1274,7 @@ static u8_t att_read_rsp(struct bt_att_chan *chan, u8_t op, u8_t rsp,
return 0;
}
(void)bt_att_chan_send(chan, data.buf, chan_rsp_sent);
bt_att_chan_send_rsp(chan, data.buf, chan_rsp_sent);
return 0;
}
@@ -1235,7 +1352,7 @@ static u8_t att_read_mult_req(struct bt_att_chan *chan, struct net_buf *buf)
}
}
(void)bt_att_chan_send(chan, data.buf, chan_rsp_sent);
bt_att_chan_send_rsp(chan, data.buf, chan_rsp_sent);
return 0;
}
@@ -1322,7 +1439,7 @@ static u8_t att_read_mult_vl_req(struct bt_att_chan *chan, struct net_buf *buf)
}
}
(void)bt_att_chan_send(chan, data.buf, chan_rsp_sent);
bt_att_chan_send_rsp(chan, data.buf, chan_rsp_sent);
return 0;
}
@@ -1438,7 +1555,7 @@ static u8_t att_read_group_rsp(struct bt_att_chan *chan, struct bt_uuid *uuid,
return 0;
}
(void)bt_att_chan_send(chan, data.buf, chan_rsp_sent);
bt_att_chan_send_rsp(chan, data.buf, chan_rsp_sent);
return 0;
}
@@ -1581,7 +1698,7 @@ static u8_t att_write_rsp(struct bt_att_chan *chan, u8_t req, u8_t rsp,
}
if (data.buf) {
(void)bt_att_chan_send(chan, data.buf, chan_rsp_sent);
bt_att_chan_send_rsp(chan, data.buf, chan_rsp_sent);
}
return 0;
@@ -1705,7 +1822,7 @@ static u8_t att_prep_write_rsp(struct bt_att_chan *chan, u16_t handle,
net_buf_add(data.buf, len);
memcpy(rsp->value, value, len);
(void)bt_att_chan_send(chan, data.buf, chan_rsp_sent);
bt_att_chan_send_rsp(chan, data.buf, chan_rsp_sent);
return 0;
}
@@ -1768,7 +1885,7 @@ static u8_t att_exec_write_rsp(struct bt_att_chan *chan, u8_t flags)
return BT_ATT_ERR_UNLIKELY;
}
(void)bt_att_chan_send(chan, buf, chan_rsp_sent);
bt_att_chan_send_rsp(chan, buf, chan_rsp_sent);
return 0;
}
@@ -2054,7 +2171,7 @@ static u8_t att_indicate(struct bt_att_chan *chan, struct net_buf *buf)
return 0;
}
(void)bt_att_chan_send(chan, buf, chan_cfm_sent);
bt_att_chan_send_rsp(chan, buf, chan_cfm_sent);
return 0;
}
@@ -2383,12 +2500,12 @@ static void att_reset(struct bt_att *att)
#if CONFIG_BT_ATT_PREPARE_COUNT > 0
/* Discard queued buffers */
while ((buf = k_fifo_get(&att->prep_queue, K_NO_WAIT))) {
while ((buf = net_buf_get(&att->prep_queue, K_NO_WAIT))) {
net_buf_unref(buf);
}
#endif /* CONFIG_BT_ATT_PREPARE_COUNT > 0 */
while ((buf = k_fifo_get(&att->tx_queue, K_NO_WAIT))) {
while ((buf = net_buf_get(&att->tx_queue, K_NO_WAIT))) {
net_buf_unref(buf);
}
@@ -2409,6 +2526,7 @@ static void att_reset(struct bt_att *att)
static void att_chan_detach(struct bt_att_chan *chan)
{
struct net_buf *buf;
int i;
BT_DBG("chan %p", chan);
@@ -2420,6 +2538,11 @@ static void att_chan_detach(struct bt_att_chan *chan)
k_sem_give(&chan->tx_sem);
}
/* Release pending buffers */
while ((buf = net_buf_get(&chan->tx_queue, K_NO_WAIT))) {
net_buf_unref(buf);
}
if (chan->req) {
/* Notify outstanding request */
att_handle_rsp(chan, NULL, 0, BT_ATT_ERR_UNLIKELY);
@@ -2557,8 +2680,8 @@ static void bt_att_encrypt_change(struct bt_l2cap_chan *chan,
BT_DBG("Retrying");
/* Resend buffer */
(void)bt_att_chan_send(att_chan, att_chan->req->buf,
chan_cb(att_chan->req->buf));
bt_att_chan_send_rsp(att_chan, att_chan->req->buf,
chan_cb(att_chan->req->buf));
att_chan->req->buf = NULL;
}
@@ -2637,6 +2760,7 @@ static struct bt_att_chan *att_chan_new(struct bt_att *att, atomic_val_t flags)
(void)memset(chan, 0, sizeof(*chan));
chan->chan.chan.ops = &ops;
k_fifo_init(&chan->tx_queue);
k_sem_init(&chan->tx_sem, CONFIG_BT_ATT_TX_MAX, CONFIG_BT_ATT_TX_MAX);
atomic_set(chan->flags, flags);
chan->att = att;
@@ -2830,8 +2954,8 @@ int bt_att_send(struct bt_conn *conn, struct net_buf *buf, bt_conn_tx_cb_t cb,
* cannot be used with a custom user_data.
*/
if (cb) {
bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, buf, cb, user_data);
return 0;
return bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, buf, cb,
user_data);
}
ret = 0;
@@ -2846,7 +2970,7 @@ int bt_att_send(struct bt_conn *conn, struct net_buf *buf, bt_conn_tx_cb_t cb,
if (ret < 0) {
/* Queue buffer to be send later */
BT_DBG("Queueing buffer %p", buf);
k_fifo_put(&att->tx_queue, buf);
net_buf_put(&att->tx_queue, buf);
}
return 0;

View File

@@ -404,9 +404,60 @@ static int cmd_write(const struct shell *shell, size_t argc, char *argv[])
return err;
}
static struct write_stats {
uint32_t count;
uint32_t len;
uint32_t total;
uint32_t rate;
} write_stats;
static void update_write_stats(uint16_t len)
{
static uint32_t cycle_stamp;
uint32_t delta;
delta = k_cycle_get_32() - cycle_stamp;
delta = (uint32_t)k_cyc_to_ns_floor64(delta);
if (!delta) {
delta = 1;
}
write_stats.count++;
write_stats.total += len;
/* if last data rx-ed was greater than 1 second in the past,
* reset the metrics.
*/
if (delta > 1000000000) {
write_stats.len = 0U;
write_stats.rate = 0U;
cycle_stamp = k_cycle_get_32();
} else {
write_stats.len += len;
write_stats.rate = ((uint64_t)write_stats.len << 3) *
1000000000U / delta;
}
}
static void reset_write_stats(void)
{
memset(&write_stats, 0, sizeof(write_stats));
}
static void print_write_stats(void)
{
shell_print(ctx_shell, "Write #%u: %u bytes (%u bps)",
write_stats.count, write_stats.total, write_stats.rate);
}
static void write_without_rsp_cb(struct bt_conn *conn, void *user_data)
{
shell_print(ctx_shell, "Write transmission complete");
uint16_t len = POINTER_TO_UINT(user_data);
update_write_stats(len);
print_write_stats();
}
static int cmd_write_without_rsp(const struct shell *shell,
@@ -428,6 +479,7 @@ static int cmd_write_without_rsp(const struct shell *shell,
if (!sign) {
if (!strcmp(argv[0], "write-without-response-cb")) {
func = write_without_rsp_cb;
reset_write_stats();
}
}
@@ -458,10 +510,14 @@ static int cmd_write_without_rsp(const struct shell *shell,
while (repeat--) {
err = bt_gatt_write_without_response_cb(default_conn, handle,
gatt_write_buf, len,
sign, func, NULL);
sign, func,
UINT_TO_POINTER(len));
if (err) {
break;
}
k_yield();
}
shell_print(shell, "Write Complete (err %d)", err);
@@ -844,17 +900,11 @@ static ssize_t read_met(struct bt_conn *conn, const struct bt_gatt_attr *attr,
value_len);
}
static u32_t write_count;
static u32_t write_len;
static u32_t write_rate;
static ssize_t write_met(struct bt_conn *conn, const struct bt_gatt_attr *attr,
const void *buf, u16_t len, u16_t offset,
u8_t flags)
{
u8_t *value = attr->user_data;
static u32_t cycle_stamp;
u32_t delta;
if (offset + len > sizeof(met_char_value)) {
return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
@@ -862,22 +912,7 @@ static ssize_t write_met(struct bt_conn *conn, const struct bt_gatt_attr *attr,
memcpy(value + offset, buf, len);
delta = k_cycle_get_32() - cycle_stamp;
delta = (u32_t)k_cyc_to_ns_floor64(delta);
/* if last data rx-ed was greater than 1 second in the past,
* reset the metrics.
*/
if (delta > 1000000000) {
write_count = 0U;
write_len = 0U;
write_rate = 0U;
cycle_stamp = k_cycle_get_32();
} else {
write_count++;
write_len += len;
write_rate = ((u64_t)write_len << 3) * 1000000000U / delta;
}
update_write_stats(len);
return len;
}
@@ -898,10 +933,8 @@ static int cmd_metrics(const struct shell *shell, size_t argc, char *argv[])
int err = 0;
if (argc < 2) {
shell_print(shell, "Write: count= %u, len= %u, rate= %u bps.",
write_count, write_len, write_rate);
return -ENOEXEC;
print_write_stats();
return 0;
}
if (!strcmp(argv[1], "on")) {
@@ -1063,9 +1096,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(gatt_cmds,
SHELL_CMD_ARG(set, NULL, "<handle> [data...]", cmd_set, 2, 255),
SHELL_CMD_ARG(show-db, NULL, "[uuid] [num_matches]", cmd_show_db, 1, 2),
#if defined(CONFIG_BT_GATT_DYNAMIC_DB)
SHELL_CMD_ARG(metrics, NULL,
"register vendr char and measure rx <value: on, off>",
cmd_metrics, 2, 0),
SHELL_CMD_ARG(metrics, NULL, "[value: on, off]", cmd_metrics, 1, 1),
SHELL_CMD_ARG(register, NULL,
"register pre-predefined test service",
cmd_register_test_svc, 1, 0),

View File

@@ -921,9 +921,9 @@ int coap_append_size2_option(struct coap_packet *cpkt,
return coap_append_option_int(cpkt, COAP_OPTION_SIZE2, ctx->total_size);
}
static int get_block_option(const struct coap_packet *cpkt, u16_t code)
int coap_get_option_int(const struct coap_packet *cpkt, u16_t code)
{
struct coap_option option;
struct coap_option option = {};
unsigned int val;
int count = 1;
@@ -1018,10 +1018,10 @@ int coap_update_from_block(const struct coap_packet *cpkt,
{
int r, block1, block2, size1, size2;
block1 = get_block_option(cpkt, COAP_OPTION_BLOCK1);
block2 = get_block_option(cpkt, COAP_OPTION_BLOCK2);
size1 = get_block_option(cpkt, COAP_OPTION_SIZE1);
size2 = get_block_option(cpkt, COAP_OPTION_SIZE2);
block1 = coap_get_option_int(cpkt, COAP_OPTION_BLOCK1);
block2 = coap_get_option_int(cpkt, COAP_OPTION_BLOCK2);
size1 = coap_get_option_int(cpkt, COAP_OPTION_SIZE1);
size2 = coap_get_option_int(cpkt, COAP_OPTION_SIZE2);
size1 = size1 == -ENOENT ? 0 : size1;
size2 = size2 == -ENOENT ? 0 : size2;
@@ -1049,9 +1049,9 @@ size_t coap_next_block(const struct coap_packet *cpkt,
int block;
if (is_request(cpkt)) {
block = get_block_option(cpkt, COAP_OPTION_BLOCK1);
block = coap_get_option_int(cpkt, COAP_OPTION_BLOCK1);
} else {
block = get_block_option(cpkt, COAP_OPTION_BLOCK2);
block = coap_get_option_int(cpkt, COAP_OPTION_BLOCK2);
}
if (!GET_MORE(block)) {
@@ -1236,20 +1236,6 @@ void coap_pendings_clear(struct coap_pending *pendings, size_t len)
}
}
static int get_observe_option(const struct coap_packet *cpkt)
{
struct coap_option option = {};
u16_t count = 1U;
int r;
r = coap_find_options(cpkt, COAP_OPTION_OBSERVE, &option, count);
if (r <= 0) {
return -ENOENT;
}
return coap_option_value_to_int(&option);
}
struct coap_reply *coap_response_received(
const struct coap_packet *response,
const struct sockaddr *from,
@@ -1280,7 +1266,7 @@ struct coap_reply *coap_response_received(
continue;
}
age = get_observe_option(response);
age = coap_get_option_int(response, COAP_OPTION_OBSERVE);
if (age > 0) {
/* age == 2 means that the notifications wrapped,
* or this is the first one
@@ -1315,7 +1301,7 @@ void coap_reply_init(struct coap_reply *reply,
reply->tkl = tkl;
age = get_observe_option(request);
age = coap_get_option_int(request, COAP_OPTION_OBSERVE);
/* It means that the request enabled observing a resource */
if (age == 0) {
@@ -1357,7 +1343,7 @@ int coap_resource_notify(struct coap_resource *resource)
bool coap_request_is_observe(const struct coap_packet *request)
{
return get_observe_option(request) == 0;
return coap_get_option_int(request, COAP_OPTION_OBSERVE) == 0;
}
void coap_observer_init(struct coap_observer *observer,

View File

@@ -142,10 +142,6 @@ static int sock_nfds;
/* TODO: figure out what's correct value */
#define TIMEOUT_BLOCKWISE_TRANSFER_MS (MSEC_PER_SEC * 30)
#define GET_BLOCK_NUM(v) ((v) >> 4)
#define GET_BLOCK_SIZE(v) (((v) & 0x7))
#define GET_MORE(v) (!!((v) & 0x08))
struct block_context {
struct coap_block_context ctx;
s64_t timestamp;
@@ -788,20 +784,6 @@ int lwm2m_delete_obj_inst(u16_t obj_id, u16_t obj_inst_id)
/* utility functions */
static int get_option_int(const struct coap_packet *cpkt, u8_t opt)
{
struct coap_option option = {};
u16_t count = 1U;
int r;
r = coap_find_options(cpkt, opt, &option, count);
if (r <= 0) {
return -ENOENT;
}
return coap_option_value_to_int(&option);
}
static u16_t atou16(u8_t *buf, u16_t buflen, u16_t *len)
{
u16_t val = 0U;
@@ -2303,7 +2285,7 @@ int lwm2m_write_handler(struct lwm2m_engine_obj_inst *obj_inst,
if (res->post_write_cb) {
/* Get block1 option for checking MORE block flag */
ret = get_option_int(msg->in.in_cpkt, COAP_OPTION_BLOCK1);
ret = coap_get_option_int(msg->in.in_cpkt, COAP_OPTION_BLOCK1);
if (ret >= 0) {
last_block = !GET_MORE(ret);
@@ -3398,7 +3380,8 @@ static int handle_request(struct coap_packet *request,
}
/* check for observe */
observe = get_option_int(msg->in.in_cpkt, COAP_OPTION_OBSERVE);
observe = coap_get_option_int(msg->in.in_cpkt,
COAP_OPTION_OBSERVE);
msg->code = COAP_RESPONSE_CODE_CONTENT;
break;
@@ -3443,7 +3426,7 @@ static int handle_request(struct coap_packet *request,
coap_packet_get_payload(msg->in.in_cpkt, &payload_len);
/* Check for block transfer */
r = get_option_int(msg->in.in_cpkt, COAP_OPTION_BLOCK1);
r = coap_get_option_int(msg->in.in_cpkt, COAP_OPTION_BLOCK1);
if (r > 0) {
last_block = !GET_MORE(r);

View File

@@ -0,0 +1,12 @@
CONFIG_FILE_SYSTEM=y
CONFIG_LOG=y
CONFIG_FAT_FILESYSTEM_ELM=y
CONFIG_FS_FATFS_LFN=y
CONFIG_DISK_ACCESS_FLASH=y
CONFIG_DISK_FLASH_DEV_NAME="flash_ctrl"
CONFIG_DISK_FLASH_START=0
CONFIG_DISK_FLASH_MAX_RW_SIZE=256
CONFIG_DISK_ERASE_BLOCK_SIZE=0x1000
CONFIG_DISK_FLASH_ERASE_ALIGNMENT=0x1000
CONFIG_DISK_VOLUME_SIZE=0x200000
CONFIG_ZTEST=y

View File

@@ -9,7 +9,12 @@
#include <fs/fs.h>
#define FATFS_MNTP "/NAND:"
#if IS_ENABLED(CONFIG_FS_FATFS_LFN)
#define TEST_FILE FATFS_MNTP \
"/testlongfilenamethatsmuchlongerthan8.3chars.text"
#else
#define TEST_FILE FATFS_MNTP"/testfile.txt"
#endif /* IS_ENABLED(CONFIG_FS_FATFS_LFN) */
#define TEST_DIR FATFS_MNTP"/testdir"
#define TEST_DIR_FILE FATFS_MNTP"/testdir/testfile.txt"

View File

@@ -106,7 +106,7 @@ static int test_rmdir(void)
int res;
struct fs_dir_t dirp;
static struct fs_dirent entry;
char file_path[80];
char file_path[80 + MAX_FILE_NAME];
TC_PRINT("\nrmdir tests:\n");

View File

@@ -34,6 +34,10 @@ static int test_file_open(void)
TC_PRINT("Opened file %s\n", TEST_FILE);
if (check_file_dir_exists(TEST_FILE)) {
TC_PRINT("File now exists %s\n", TEST_FILE);
}
return res;
}

View File

@@ -2,3 +2,7 @@ tests:
filesystem.fat.api:
platform_whitelist: native_posix
tags: filesystem
filesystem.fat.api.lfn:
extra_args: CONF_FILE="prj_lfn.conf"
platform_whitelist: native_posix
tags: filesystem