[修改] 增加freeRTOS
1. 版本FreeRTOSv202212.01,命名为kernel;
This commit is contained in:
63
kernel/FreeRTOS-Plus/Source/Utilities/backoff_algorithm/.github/CONTRIBUTING.md
vendored
Normal file
63
kernel/FreeRTOS-Plus/Source/Utilities/backoff_algorithm/.github/CONTRIBUTING.md
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
# Contributing Guidelines
|
||||
|
||||
Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional
|
||||
documentation, we greatly value feedback and contributions from our community.
|
||||
|
||||
Please read through this document before submitting any issues or pull requests to ensure we have all the necessary
|
||||
information to effectively respond to your bug report or contribution.
|
||||
|
||||
|
||||
## Reporting Bugs/Feature Requests
|
||||
|
||||
We welcome you to use the GitHub issue tracker to report bugs or suggest features.
|
||||
|
||||
When filing an issue, please check [existing open](https://github.com/FreeRTOS/backoffAlgorithm/issues), or [recently closed](https://github.com/FreeRTOS/backoffAlgorithm/issues?q=is%3Aissue+is%3Aclosed), issues to make sure somebody else hasn't already
|
||||
reported the issue. Please try to include as much information as you can. Details like these are incredibly useful:
|
||||
|
||||
* A reproducible test case or series of steps
|
||||
* The version of our code being used
|
||||
* Any modifications you've made relevant to the bug
|
||||
* Anything unusual about your environment or deployment
|
||||
|
||||
|
||||
## Contributing via Pull Requests
|
||||
Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that:
|
||||
|
||||
1. You are working against the latest source on the *main* branch.
|
||||
1. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already.
|
||||
1. You open an issue to discuss any significant work - we would hate for your time to be wasted.
|
||||
|
||||
To send us a pull request, please:
|
||||
|
||||
1. Fork the repository.
|
||||
1. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
|
||||
1. Ensure that your contributions conform to the [style guide](https://docs.aws.amazon.com/embedded-csdk/202011.00/lib-ref/docs/doxygen/output/html/guide_developer_styleguide.html).
|
||||
1. Format your code with uncrustify, using the config available in [FreeRTOS/CI-CD-Github-Actions](https://github.com/FreeRTOS/CI-CD-Github-Actions/blob/main/formatting/uncrustify.cfg).
|
||||
1. Ensure local tests pass.
|
||||
1. Commit to your fork using clear commit messages.
|
||||
1. Send us a pull request, answering any default questions in the pull request interface.
|
||||
1. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
|
||||
|
||||
GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
|
||||
[creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
|
||||
|
||||
|
||||
## Finding contributions to work on
|
||||
Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels ((enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any ['help wanted'](https://github.com/FreeRTOS/backoffAlgorithm/labels?q=help+wanted) issues is a great place to start.
|
||||
|
||||
|
||||
## Code of Conduct
|
||||
This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
|
||||
For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
|
||||
opensource-codeofconduct@amazon.com with any additional questions or comments.
|
||||
|
||||
|
||||
## Security issue notifications
|
||||
If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](https://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.
|
||||
|
||||
|
||||
## Licensing
|
||||
|
||||
See the [LICENSE](../LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution.
|
||||
|
||||
We may ask you to sign a [Contributor License Agreement (CLA)](https://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes.
|
||||
@ -0,0 +1,9 @@
|
||||
{
|
||||
"lib_name": "backoffAlgorithm",
|
||||
"src": [
|
||||
"source/backoff_algorithm.c"
|
||||
],
|
||||
"include": [
|
||||
"source/include"
|
||||
]
|
||||
}
|
||||
124
kernel/FreeRTOS-Plus/Source/Utilities/backoff_algorithm/.github/workflows/ci.yml
vendored
Normal file
124
kernel/FreeRTOS-Plus/Source/Utilities/backoff_algorithm/.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
name: CI Checks
|
||||
on:
|
||||
push:
|
||||
branches: ["**"]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
unittest:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Clone This Repo
|
||||
uses: actions/checkout@v2
|
||||
- name: Build
|
||||
run: |
|
||||
sudo apt-get install -y lcov sed
|
||||
cmake -S test -B build/ \
|
||||
-G "Unix Makefiles" \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-DBUILD_UNIT_TESTS=ON \
|
||||
-DCMAKE_C_FLAGS='--coverage -Wall -Wextra -Werror'
|
||||
make -C build/ all
|
||||
- name: Test
|
||||
run: |
|
||||
cd build/
|
||||
ctest -E system --output-on-failure
|
||||
cd ..
|
||||
- name: Run Coverage
|
||||
run: |
|
||||
make -C build/ coverage
|
||||
declare -a EXCLUDE=("\*test\*" "\*CMakeCCompilerId\*" "\*mocks\*")
|
||||
echo ${EXCLUDE[@]} | xargs lcov --rc lcov_branch_coverage=1 -r build/coverage.info -o build/coverage.info
|
||||
lcov --rc lcov_branch_coverage=1 --list build/coverage.info
|
||||
- name: Check Coverage
|
||||
uses: FreeRTOS/CI-CD-Github-Actions/coverage-cop@main
|
||||
with:
|
||||
path: ./build/coverage.info
|
||||
build-code-example:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Clone This Repo
|
||||
uses: actions/checkout@v2
|
||||
- name: Build code example
|
||||
run: |
|
||||
cmake -S test -B Build -DBUILD_CODE_EXAMPLE=ON
|
||||
make -C Build code_example_posix -j8
|
||||
complexity:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Check complexity
|
||||
uses: FreeRTOS/CI-CD-Github-Actions/complexity@main
|
||||
with:
|
||||
path: ./
|
||||
doxygen:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Run doxygen build
|
||||
uses: FreeRTOS/CI-CD-Github-Actions/doxygen@main
|
||||
with:
|
||||
path: ./
|
||||
spell-check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Clone This Repo
|
||||
uses: actions/checkout@v2
|
||||
- name: Run spellings check
|
||||
uses: FreeRTOS/CI-CD-Github-Actions/spellings@main
|
||||
with:
|
||||
path: ./
|
||||
formatting:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Check formatting
|
||||
uses: FreeRTOS/CI-CD-Github-Actions/formatting@main
|
||||
with:
|
||||
path: ./
|
||||
git-secrets:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Checkout awslabs/git-secrets
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: awslabs/git-secrets
|
||||
ref: master
|
||||
path: git-secrets
|
||||
- name: Install git-secrets
|
||||
run: cd git-secrets && sudo make install && cd ..
|
||||
- name: Run git-secrets
|
||||
run: |
|
||||
git-secrets --register-aws
|
||||
git-secrets --scan
|
||||
custom-standard-c-header:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Clone This Repo
|
||||
uses: actions/checkout@v2
|
||||
- name: Build
|
||||
run: |
|
||||
mkdir -p override-include
|
||||
cp source/include/stdint.readme override-include/stdint.h
|
||||
cmake -S test -B build/ \
|
||||
-G "Unix Makefiles" \
|
||||
-DBUILD_CLONE_SUBMODULES=ON \
|
||||
-DCMAKE_C_FLAGS='-Wall -Wextra -Werror -I../override-include'
|
||||
make -C build/ coverity_analysis
|
||||
memory_statistics:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
- name: Install Python3
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.7.10'
|
||||
- name: Measure sizes
|
||||
uses: FreeRTOS/CI-CD-Github-Actions/memory_statistics@main
|
||||
with:
|
||||
config: .github/memory_statistics_config.json
|
||||
check_against: docs/doxygen/include/size_table.md
|
||||
11
kernel/FreeRTOS-Plus/Source/Utilities/backoff_algorithm/.github/workflows/doxygen.yml
vendored
Normal file
11
kernel/FreeRTOS-Plus/Source/Utilities/backoff_algorithm/.github/workflows/doxygen.yml
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
name: Doxygen Generation
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
doxygen-generation:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Doxygen generation
|
||||
uses: FreeRTOS/CI-CD-Github-Actions/doxygen-generation@main
|
||||
139
kernel/FreeRTOS-Plus/Source/Utilities/backoff_algorithm/.github/workflows/release.yml
vendored
Normal file
139
kernel/FreeRTOS-Plus/Source/Utilities/backoff_algorithm/.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,139 @@
|
||||
name: Release automation
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
commit_id:
|
||||
description: 'Commit ID to tag and create a release for'
|
||||
required: true
|
||||
version_number:
|
||||
description: 'Release Version Number (Eg, v1.0.0)'
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
tag-commit:
|
||||
name: Tag commit
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ github.event.inputs.commit_id }}
|
||||
- name: Configure git identity
|
||||
run: |
|
||||
git config --global user.name ${{ github.actor }}
|
||||
git config --global user.email ${{ github.actor }}@users.noreply.github.com
|
||||
- name: create a new branch that references commit id
|
||||
run: git checkout -b ${{ github.event.inputs.version_number }} ${{ github.event.inputs.commit_id }}
|
||||
- name: Generate SBOM
|
||||
uses: FreeRTOS/CI-CD-Github-Actions/sbom-generator@main
|
||||
with:
|
||||
repo_path: ./
|
||||
source_path: ./source
|
||||
- name: commit SBOM file
|
||||
run: |
|
||||
git add .
|
||||
git commit -m 'Update SBOM'
|
||||
git push -u origin ${{ github.event.inputs.version_number }}
|
||||
- name: Tag Commit and Push to remote
|
||||
run: |
|
||||
git tag ${{ github.event.inputs.version_number }} -a -m "backoffAlgorithm Library ${{ github.event.inputs.version_number }}"
|
||||
git push origin --tags
|
||||
- name: Verify tag on remote
|
||||
run: |
|
||||
git tag -d ${{ github.event.inputs.version_number }}
|
||||
git remote update
|
||||
git checkout tags/${{ github.event.inputs.version_number }}
|
||||
git diff ${{ github.event.inputs.commit_id }} tags/${{ github.event.inputs.version_number }}
|
||||
create-zip:
|
||||
needs: tag-commit
|
||||
name: Create ZIP and verify package for release asset.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Install ZIP tools
|
||||
run: sudo apt-get install zip unzip
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ github.event.inputs.commit_id }}
|
||||
path: backoffAlgorithm
|
||||
submodules: recursive
|
||||
- name: Checkout disabled submodules
|
||||
run: |
|
||||
cd backoffAlgorithm
|
||||
git submodule update --init --checkout --recursive
|
||||
- name: Create ZIP
|
||||
run: |
|
||||
zip -r backoffAlgorithm-${{ github.event.inputs.version_number }}.zip backoffAlgorithm -x "*.git*"
|
||||
ls ./
|
||||
- name: Validate created ZIP
|
||||
run: |
|
||||
mkdir zip-check
|
||||
mv backoffAlgorithm-${{ github.event.inputs.version_number }}.zip zip-check
|
||||
cd zip-check
|
||||
unzip backoffAlgorithm-${{ github.event.inputs.version_number }}.zip -d backoffAlgorithm-${{ github.event.inputs.version_number }}
|
||||
ls backoffAlgorithm-${{ github.event.inputs.version_number }}
|
||||
diff -r -x "*.git*" backoffAlgorithm-${{ github.event.inputs.version_number }}/backoffAlgorithm/ ../backoffAlgorithm/
|
||||
cd ../
|
||||
- name: Build
|
||||
run: |
|
||||
cd zip-check/backoffAlgorithm-${{ github.event.inputs.version_number }}/backoffAlgorithm
|
||||
sudo apt-get install -y lcov
|
||||
cmake -S test -B build/ \
|
||||
-G "Unix Makefiles" \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-DBUILD_CLONE_SUBMODULES=ON \
|
||||
-DCMAKE_C_FLAGS='--coverage -Wall -Wextra -Werror'
|
||||
make -C build/ all
|
||||
- name: Test
|
||||
run: |
|
||||
cd zip-check/backoffAlgorithm-${{ github.event.inputs.version_number }}/backoffAlgorithm/build/
|
||||
ctest -E system --output-on-failure
|
||||
cd ..
|
||||
- name: Create artifact of ZIP
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: backoffAlgorithm-${{ github.event.inputs.version_number }}.zip
|
||||
path: zip-check/backoffAlgorithm-${{ github.event.inputs.version_number }}.zip
|
||||
deploy-doxygen:
|
||||
needs: tag-commit
|
||||
name: Deploy doxygen documentation
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Doxygen generation
|
||||
uses: FreeRTOS/CI-CD-Github-Actions/doxygen-generation@main
|
||||
with:
|
||||
ref: ${{ github.event.inputs.version_number }}
|
||||
add_release: "true"
|
||||
create-release:
|
||||
needs:
|
||||
- create-zip
|
||||
- deploy-doxygen
|
||||
name: Create Release and Upload Release Asset
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.event.inputs.version_number }}
|
||||
release_name: ${{ github.event.inputs.version_number }}
|
||||
body: Release ${{ github.event.inputs.version_number }} of the backoffAlgorithm Library.
|
||||
draft: false
|
||||
prerelease: false
|
||||
- name: Download ZIP artifact
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: backoffAlgorithm-${{ github.event.inputs.version_number }}.zip
|
||||
- name: Upload Release Asset
|
||||
id: upload-release-asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./backoffAlgorithm-${{ github.event.inputs.version_number }}.zip
|
||||
asset_name: backoffAlgorithm-${{ github.event.inputs.version_number }}.zip
|
||||
asset_content_type: application/zip
|
||||
13
kernel/FreeRTOS-Plus/Source/Utilities/backoff_algorithm/.gitignore
vendored
Normal file
13
kernel/FreeRTOS-Plus/Source/Utilities/backoff_algorithm/.gitignore
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
# Ignore documentation output.
|
||||
**/docs/**/output/*
|
||||
|
||||
# Ignore CMake build directory.
|
||||
build/
|
||||
|
||||
# Ignore build artifacts
|
||||
*.o
|
||||
|
||||
# Ignore code coverage artifacts
|
||||
*.gcda
|
||||
*.gcno
|
||||
*.gcov
|
||||
4
kernel/FreeRTOS-Plus/Source/Utilities/backoff_algorithm/.gitmodules
vendored
Normal file
4
kernel/FreeRTOS-Plus/Source/Utilities/backoff_algorithm/.gitmodules
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
[submodule "test/unit-test/Unity"]
|
||||
path = test/unit-test/Unity
|
||||
url = https://github.com/ThrowTheSwitch/Unity
|
||||
update = none
|
||||
@ -0,0 +1,36 @@
|
||||
# Changelog for backoffAlgorithm Library
|
||||
|
||||
## v1.3.0 (October 2022)
|
||||
|
||||
### Changes
|
||||
|
||||
- [#38](https://github.com/FreeRTOS/backoffAlgorithm/pull/38) MISRA compliance update
|
||||
|
||||
## v1.2.0 (November 2021)
|
||||
|
||||
### Changes
|
||||
|
||||
- [#31](https://github.com/FreeRTOS/backoffAlgorithm/pull/31) Update doxygen version for documentation.
|
||||
- [#30](https://github.com/FreeRTOS/backoffAlgorithm/pull/30) Add code examples to documentation.
|
||||
|
||||
## v1.1.0 (July 2021)
|
||||
|
||||
### Changes
|
||||
|
||||
- [#29](https://github.com/FreeRTOS/backoffAlgorithm/pull/29) Set BACKOFF_ALGORITHM_RETRY_FOREVER to be nonzero and add header guards for C++ linkage.
|
||||
- [#27](https://github.com/FreeRTOS/backoffAlgorithm/pull/27) Fix incorrect comment about use of BACKOFF_ALGORITHM_RETRY_FOREVER constant in BackoffAlgorithm_GetNextBackoff API.
|
||||
|
||||
## v1.0.1 (February 2021)
|
||||
|
||||
### Changes
|
||||
|
||||
- [#24](https://github.com/FreeRTOS/backoffAlgorithm/pull/24) Fix MISRA 10.4 and 10.7 rule violations, and add documentation of MISRA compliance.
|
||||
- [#18](https://github.com/FreeRTOS/backoffAlgorithm/pull/18), [#19](https://github.com/FreeRTOS/backoffAlgorithm/pull/19), and [#20](https://github.com/FreeRTOS/backoffAlgorithm/pull/20) Documentation fixes.
|
||||
|
||||
## v1.0.0 (December 2020)
|
||||
|
||||
This is the first release of the backoffAlgorithm library in this repository.
|
||||
|
||||
The backoffAlgorithm library is a utility library to calculate backoff period using an exponential backoff with jitter algorithm for retrying network operations (like failed network connection with server).
|
||||
This library uses the "Full Jitter" strategy for the exponential backoff with jitter algorithm.
|
||||
More information about the algorithm can be seen in the [Exponential Backoff and Jitter](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/) AWS blog.
|
||||
@ -0,0 +1,19 @@
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@ -0,0 +1,16 @@
|
||||
# MISRA Compliance
|
||||
|
||||
The backoffAlgorithm library files conform to the [MISRA C:2012](https://www.misra.org.uk)
|
||||
guidelines, with some noted exceptions. Compliance is checked with Coverity static analysis.
|
||||
The specific deviations, suppressed inline, are listed below.
|
||||
|
||||
Additionally, [MISRA configuration file](https://github.com/FreeRTOS/backoffAlgorithm/blob/main/tools/coverity/misra.config) contains the project wide deviations.
|
||||
|
||||
|
||||
### Suppressed with Coverity Comments
|
||||
To find the violation references in the source files run grep on the source code
|
||||
with ( Assuming rule 11.4 violation; with justification in point 2 ):
|
||||
```
|
||||
grep 'MISRA Ref 11.4.2' . -rI
|
||||
```
|
||||
*None.*
|
||||
@ -0,0 +1,160 @@
|
||||
## backoffAlgorithm Library
|
||||
|
||||
This repository contains the backoffAlgorithm library, a utility library to calculate backoff period using an exponential backoff with jitter algorithm for retrying network operations (like failed network connection with server).
|
||||
This library uses the "Full Jitter" strategy for the exponential backoff with jitter algorithm.
|
||||
More information about the algorithm can be seen in the [Exponential Backoff and Jitter](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/) AWS blog.
|
||||
|
||||
The backoffAlgorithm library is distributed under the [MIT Open Source License](LICENSE).
|
||||
|
||||
Exponential backoff with jitter is typically used when retrying a failed network
|
||||
connection or operation request with the server. An exponential backoff with jitter helps to
|
||||
mitigate failed network operations with servers, that are caused due to network congestion or high request load on
|
||||
the server, by spreading out retry requests across multiple devices attempting network operations.
|
||||
Besides, in an environment with poor connectivity, a client can get disconnected at any time.
|
||||
A backoff strategy helps the client to conserve battery by not repeatedly attempting reconnections when they are
|
||||
unlikely to succeed.
|
||||
|
||||
See memory requirements for this library [here](./docs/doxygen/include/size_table.md).
|
||||
|
||||
**backoffAlgorithm v1.3.0 [source code](https://github.com/FreeRTOS/backoffAlgorithm/tree/v1.3.0/source) is part of the [FreeRTOS 202210.00 LTS](https://github.com/FreeRTOS/FreeRTOS-LTS/tree/202210.00-LTS) release.**
|
||||
|
||||
**backoffAlgorithm v1.0.0 [source code](https://github.com/FreeRTOS/backoffAlgorithm/tree/v1.0.0/source) is part of the [FreeRTOS 202012.00 LTS](https://github.com/FreeRTOS/FreeRTOS-LTS/tree/202012.00-LTS) release.**
|
||||
|
||||
## Reference example
|
||||
|
||||
The example below shows how to use the backoffAlgorithm library on a POSIX platform to retry a DNS resolution query for `amazon.com`.
|
||||
|
||||
```c
|
||||
#include "backoff_algorithm.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
/* The maximum number of retries for the example code. */
|
||||
#define RETRY_MAX_ATTEMPTS ( 5U )
|
||||
|
||||
/* The maximum back-off delay (in milliseconds) for between retries in the example. */
|
||||
#define RETRY_MAX_BACKOFF_DELAY_MS ( 5000U )
|
||||
|
||||
/* The base back-off delay (in milliseconds) for retry configuration in the example. */
|
||||
#define RETRY_BACKOFF_BASE_MS ( 500U )
|
||||
|
||||
int main()
|
||||
{
|
||||
/* Variables used in this example. */
|
||||
BackoffAlgorithmStatus_t retryStatus = BackoffAlgorithmSuccess;
|
||||
BackoffAlgorithmContext_t retryParams;
|
||||
char serverAddress[] = "amazon.com";
|
||||
uint16_t nextRetryBackoff = 0;
|
||||
|
||||
int32_t dnsStatus = -1;
|
||||
struct addrinfo hints;
|
||||
struct addrinfo ** pListHead = NULL;
|
||||
struct timespec tp;
|
||||
|
||||
/* Add hints to retrieve only TCP sockets in getaddrinfo. */
|
||||
( void ) memset( &hints, 0, sizeof( hints ) );
|
||||
|
||||
/* Address family of either IPv4 or IPv6. */
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
/* TCP Socket. */
|
||||
hints.ai_socktype = ( int32_t ) SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
/* Initialize reconnect attempts and interval. */
|
||||
BackoffAlgorithm_InitializeParams( &retryParams,
|
||||
RETRY_BACKOFF_BASE_MS,
|
||||
RETRY_MAX_BACKOFF_DELAY_MS,
|
||||
RETRY_MAX_ATTEMPTS );
|
||||
|
||||
|
||||
/* Seed the pseudo random number generator used in this example (with call to
|
||||
* rand() function provided by ISO C standard library) for use in backoff period
|
||||
* calculation when retrying failed DNS resolution. */
|
||||
|
||||
/* Get current time to seed pseudo random number generator. */
|
||||
( void ) clock_gettime( CLOCK_REALTIME, &tp );
|
||||
/* Seed pseudo random number generator with seconds. */
|
||||
srand( tp.tv_sec );
|
||||
|
||||
do
|
||||
{
|
||||
/* Perform a DNS lookup on the given host name. */
|
||||
dnsStatus = getaddrinfo( serverAddress, NULL, &hints, pListHead );
|
||||
|
||||
/* Retry if DNS resolution query failed. */
|
||||
if( dnsStatus != 0 )
|
||||
{
|
||||
/* Generate a random number and get back-off value (in milliseconds) for the next retry.
|
||||
* Note: It is recommended to use a random number generator that is seeded with
|
||||
* device-specific entropy source so that backoff calculation across devices is different
|
||||
* and possibility of network collision between devices attempting retries can be avoided.
|
||||
*
|
||||
* For the simplicity of this code example, the pseudo random number generator, rand()
|
||||
* function is used. */
|
||||
retryStatus = BackoffAlgorithm_GetNextBackoff( &retryParams, rand(), &nextRetryBackoff );
|
||||
|
||||
/* Wait for the calculated backoff period before the next retry attempt of querying DNS.
|
||||
* As usleep() takes nanoseconds as the parameter, we multiply the backoff period by 1000. */
|
||||
( void ) usleep( nextRetryBackoff * 1000U );
|
||||
}
|
||||
} while( ( dnsStatus != 0 ) && ( retryStatus != BackoffAlgorithmRetriesExhausted ) );
|
||||
|
||||
return dnsStatus;
|
||||
}
|
||||
```
|
||||
|
||||
## Building the library
|
||||
|
||||
A compiler that supports **C90 or later** such as *gcc* is required to build the library.
|
||||
|
||||
Additionally, the library uses a header file introduced in ISO C99, `stdint.h`. For compilers that do not provide this header file, the [source/include](source/include) directory contains [stdint.readme](source/include/stdint.readme), which can be renamed to `stdint.h` to
|
||||
build the backoffAlgorithm library.
|
||||
|
||||
For instance, if the example above is copied to a file named `example.c`, *gcc* can be used like so:
|
||||
```bash
|
||||
gcc -I source/include example.c source/backoff_algorithm.c -o example
|
||||
./example
|
||||
```
|
||||
|
||||
*gcc* can also produce an output file to be linked:
|
||||
```bash
|
||||
gcc -I source/include -c source/backoff_algorithm.c
|
||||
```
|
||||
|
||||
## Building unit tests
|
||||
|
||||
### Checkout Unity Submodule
|
||||
By default, the submodules in this repository are configured with `update=none` in [.gitmodules](.gitmodules), to avoid increasing clone time and disk space usage of other repositories (like [amazon-freertos](https://github.com/aws/amazon-freertos) that submodules this repository).
|
||||
|
||||
To build unit tests, the submodule dependency of Unity is required. Use the following command to clone the submodule:
|
||||
```
|
||||
git submodule update --checkout --init --recursive test/unit-test/Unity
|
||||
```
|
||||
|
||||
### Platform Prerequisites
|
||||
|
||||
- For running unit tests
|
||||
- C89 or later compiler like gcc
|
||||
- CMake 3.13.0 or later
|
||||
- For running the coverage target, gcov is additionally required.
|
||||
|
||||
### Steps to build Unit Tests
|
||||
|
||||
1. Go to the root directory of this repository. (Make sure that the **Unity** submodule is cloned as described [above](#checkout-unity-submodule).)
|
||||
|
||||
1. Create build directory: `mkdir build && cd build`
|
||||
|
||||
1. Run *cmake* while inside build directory: `cmake -S ../test`
|
||||
|
||||
1. Run this command to build the library and unit tests: `make all`
|
||||
|
||||
1. The generated test executables will be present in `build/bin/tests` folder.
|
||||
|
||||
1. Run `ctest` to execute all tests and view the test run summary.
|
||||
|
||||
## Contributing
|
||||
|
||||
See [CONTRIBUTING.md](./.github/CONTRIBUTING.md) for information on contributing.
|
||||
@ -0,0 +1,5 @@
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you discover a potential security issue in this project, we ask that you notify AWS/Amazon Security
|
||||
via our [vulnerability reporting page](https://aws.amazon.com/security/vulnerability-reporting/) or directly via email to aws-security@amazon.com.
|
||||
Please do **not** create a public github issue.
|
||||
@ -0,0 +1,14 @@
|
||||
# This file is to add source files and include directories
|
||||
# into variables so that it can be reused from different repositories
|
||||
# in their Cmake based build system by including this file.
|
||||
#
|
||||
# Files specific to the repository such as test runner, platform tests
|
||||
# are not added to the variables.
|
||||
|
||||
# Backoff Algorithm library source files.
|
||||
set( BACKOFF_ALGORITHM_SOURCES
|
||||
"${CMAKE_CURRENT_LIST_DIR}/source/backoff_algorithm.c" )
|
||||
|
||||
# Backoff Algorithm library Public Include directories.
|
||||
set( BACKOFF_ALGORITHM_INCLUDE_PUBLIC_DIRS
|
||||
"${CMAKE_CURRENT_LIST_DIR}/source/include" )
|
||||
@ -0,0 +1,84 @@
|
||||
#include "backoff_algorithm.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
/* The maximum number of retries for the example code. */
|
||||
#define RETRY_MAX_ATTEMPTS ( 5U )
|
||||
|
||||
/* The maximum back-off delay (in milliseconds) for between retries in the example. */
|
||||
#define RETRY_MAX_BACKOFF_DELAY_MS ( 5000U )
|
||||
|
||||
/* The base back-off delay (in milliseconds) for retry configuration in the example. */
|
||||
#define RETRY_BACKOFF_BASE_MS ( 500U )
|
||||
|
||||
int main()
|
||||
{
|
||||
/* @[code_example_backoffalgorithm_initializeparams] */
|
||||
/* Variables used in this example. */
|
||||
BackoffAlgorithmStatus_t retryStatus = BackoffAlgorithmSuccess;
|
||||
BackoffAlgorithmContext_t retryParams;
|
||||
char serverAddress[] = "amazon.com";
|
||||
uint16_t nextRetryBackoff = 0;
|
||||
|
||||
/* Initialize reconnect attempts and interval. */
|
||||
BackoffAlgorithm_InitializeParams( &retryParams,
|
||||
RETRY_BACKOFF_BASE_MS,
|
||||
RETRY_MAX_BACKOFF_DELAY_MS,
|
||||
RETRY_MAX_ATTEMPTS );
|
||||
/* @[code_example_backoffalgorithm_initializeparams] */
|
||||
|
||||
int32_t dnsStatus = -1;
|
||||
struct addrinfo hints;
|
||||
struct addrinfo ** pListHead = NULL;
|
||||
struct timespec tp;
|
||||
|
||||
/* Add hints to retrieve only TCP sockets in getaddrinfo. */
|
||||
( void ) memset( &hints, 0, sizeof( hints ) );
|
||||
|
||||
/* Address family of either IPv4 or IPv6. */
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
/* TCP Socket. */
|
||||
hints.ai_socktype = ( int32_t ) SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
/* @[code_example_backoffalgorithm_getnextbackoff] */
|
||||
|
||||
/* Seed the pseudo random number generator used in this example (with call to
|
||||
* rand() function provided by ISO C standard library) for use in backoff period
|
||||
* calculation when retrying failed DNS resolution. */
|
||||
|
||||
/* Get current time to seed pseudo random number generator. */
|
||||
( void ) clock_gettime( CLOCK_REALTIME, &tp );
|
||||
/* Seed pseudo random number generator with seconds. */
|
||||
srand( tp.tv_sec );
|
||||
|
||||
do
|
||||
{
|
||||
/* Perform a DNS lookup on the given host name. */
|
||||
dnsStatus = getaddrinfo( serverAddress, NULL, &hints, pListHead );
|
||||
|
||||
/* Retry if DNS resolution query failed. */
|
||||
if( dnsStatus != 0 )
|
||||
{
|
||||
/* Generate a random number and get back-off value (in milliseconds) for the next retry.
|
||||
* Note: It is recommended to use a random number generator that is seeded with
|
||||
* device-specific entropy source so that backoff calculation across devices is different
|
||||
* and possibility of network collision between devices attempting retries can be avoided.
|
||||
*
|
||||
* For the simplicity of this code example, the pseudo random number generator, rand()
|
||||
* function is used. */
|
||||
retryStatus = BackoffAlgorithm_GetNextBackoff( &retryParams, rand(), &nextRetryBackoff );
|
||||
|
||||
/* Wait for the calculated backoff period before the next retry attempt of querying DNS.
|
||||
* As usleep() takes nanoseconds as the parameter, we multiply the backoff period by 1000. */
|
||||
( void ) usleep( nextRetryBackoff * 1000U );
|
||||
}
|
||||
} while( ( dnsStatus != 0 ) && ( retryStatus != BackoffAlgorithmRetriesExhausted ) );
|
||||
|
||||
/* @[code_example_backoffalgorithm_getnextbackoff] */
|
||||
|
||||
return dnsStatus;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,20 @@
|
||||
<table>
|
||||
<tr>
|
||||
<td colspan="3"><center><b>Code Size of backoffAlgorithm (example generated with GCC for ARM Cortex-M)</b></center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>File</b></td>
|
||||
<td><b><center>With -O1 Optimization</center></b></td>
|
||||
<td><b><center>With -Os Optimization</center></b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>backoff_algorithm.c</td>
|
||||
<td><center>0.1K</center></td>
|
||||
<td><center>0.1K</center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Total estimates</b></td>
|
||||
<td><b><center>0.1K</center></b></td>
|
||||
<td><b><center>0.1K</center></b></td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -0,0 +1,228 @@
|
||||
<doxygenlayout version="1.0">
|
||||
<!-- Generated by doxygen 1.8.20 -->
|
||||
<!-- Navigation index tabs for HTML output -->
|
||||
<navindex>
|
||||
<tab type="mainpage" visible="yes" title=""/>
|
||||
<tab type="pages" visible="yes" title="" intro=""/>
|
||||
<!-- Hide the default "Data Structures" tab and use the "Modules" tab for data
|
||||
structures. This allows internal data structures to be hidden. -->
|
||||
<tab type="modules" visible="yes" title="Data types and Constants" intro="This library defines the following data types and constants."/>
|
||||
<tab type="namespaces" visible="yes" title="">
|
||||
<tab type="namespacelist" visible="yes" title="" intro=""/>
|
||||
<tab type="namespacemembers" visible="yes" title="" intro=""/>
|
||||
</tab>
|
||||
<tab type="interfaces" visible="no" title="">
|
||||
<tab type="interfacelist" visible="no" title="" intro=""/>
|
||||
<tab type="interfaceindex" visible="no" title=""/>
|
||||
<tab type="interfacehierarchy" visible="yes" title="" intro=""/>
|
||||
</tab>
|
||||
<tab type="classes" visible="no" title="">
|
||||
<tab type="classlist" visible="no" title="" intro=""/>
|
||||
<tab type="classindex" visible="no" title=""/>
|
||||
<tab type="hierarchy" visible="no" title="" intro=""/>
|
||||
<tab type="classmembers" visible="no" title="" intro=""/>
|
||||
</tab>
|
||||
<tab type="structs" visible="no" title="">
|
||||
<tab type="structlist" visible="no" title="" intro=""/>
|
||||
<tab type="structindex" visible="no" title=""/>
|
||||
</tab>
|
||||
<tab type="exceptions" visible="no" title="">
|
||||
<tab type="exceptionlist" visible="no" title="" intro=""/>
|
||||
<tab type="exceptionindex" visible="no" title=""/>
|
||||
<tab type="exceptionhierarchy" visible="yes" title="" intro=""/>
|
||||
</tab>
|
||||
<tab type="files" visible="no" title="">
|
||||
<tab type="filelist" visible="yes" title="Files" intro="The following files are associated with this library."/>
|
||||
<tab type="globals" visible="no" title="" intro=""/>
|
||||
</tab>
|
||||
<tab type="examples" visible="yes" title="" intro=""/>
|
||||
</navindex>
|
||||
|
||||
<!-- Layout definition for a class page -->
|
||||
<class>
|
||||
<briefdescription visible="yes"/>
|
||||
<includes visible="$SHOW_INCLUDE_FILES"/>
|
||||
<inheritancegraph visible="$CLASS_GRAPH"/>
|
||||
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
|
||||
<memberdecl>
|
||||
<nestedclasses visible="yes" title=""/>
|
||||
<publictypes title=""/>
|
||||
<services title=""/>
|
||||
<interfaces title=""/>
|
||||
<publicslots title=""/>
|
||||
<signals title=""/>
|
||||
<publicmethods title=""/>
|
||||
<publicstaticmethods title=""/>
|
||||
<publicattributes title=""/>
|
||||
<publicstaticattributes title=""/>
|
||||
<protectedtypes title=""/>
|
||||
<protectedslots title=""/>
|
||||
<protectedmethods title=""/>
|
||||
<protectedstaticmethods title=""/>
|
||||
<protectedattributes title=""/>
|
||||
<protectedstaticattributes title=""/>
|
||||
<packagetypes title=""/>
|
||||
<packagemethods title=""/>
|
||||
<packagestaticmethods title=""/>
|
||||
<packageattributes title=""/>
|
||||
<packagestaticattributes title=""/>
|
||||
<properties title=""/>
|
||||
<events title=""/>
|
||||
<privatetypes title=""/>
|
||||
<privateslots title=""/>
|
||||
<privatemethods title=""/>
|
||||
<privatestaticmethods title=""/>
|
||||
<privateattributes title=""/>
|
||||
<privatestaticattributes title=""/>
|
||||
<friends title=""/>
|
||||
<related title="" subtitle=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
<memberdef>
|
||||
<inlineclasses title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<services title=""/>
|
||||
<interfaces title=""/>
|
||||
<constructors title=""/>
|
||||
<functions title=""/>
|
||||
<related title=""/>
|
||||
<variables title=""/>
|
||||
<properties title=""/>
|
||||
<events title=""/>
|
||||
</memberdef>
|
||||
<allmemberslink visible="yes"/>
|
||||
<usedfiles visible="$SHOW_USED_FILES"/>
|
||||
<authorsection visible="yes"/>
|
||||
</class>
|
||||
|
||||
<!-- Layout definition for a namespace page -->
|
||||
<namespace>
|
||||
<briefdescription visible="yes"/>
|
||||
<memberdecl>
|
||||
<nestednamespaces visible="yes" title=""/>
|
||||
<constantgroups visible="yes" title=""/>
|
||||
<interfaces visible="yes" title=""/>
|
||||
<classes visible="yes" title=""/>
|
||||
<structs visible="yes" title=""/>
|
||||
<exceptions visible="yes" title=""/>
|
||||
<typedefs title=""/>
|
||||
<sequences title=""/>
|
||||
<dictionaries title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
<memberdef>
|
||||
<inlineclasses title=""/>
|
||||
<typedefs title=""/>
|
||||
<sequences title=""/>
|
||||
<dictionaries title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
</memberdef>
|
||||
<authorsection visible="yes"/>
|
||||
</namespace>
|
||||
|
||||
<!-- Layout definition for a file page -->
|
||||
<file>
|
||||
<briefdescription visible="yes"/>
|
||||
<includes visible="$SHOW_INCLUDE_FILES"/>
|
||||
<includegraph visible="$INCLUDE_GRAPH"/>
|
||||
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
|
||||
<sourcelink visible="yes"/>
|
||||
<memberdecl>
|
||||
<interfaces visible="yes" title=""/>
|
||||
<classes visible="yes" title=""/>
|
||||
<structs visible="yes" title=""/>
|
||||
<exceptions visible="yes" title=""/>
|
||||
<namespaces visible="yes" title=""/>
|
||||
<constantgroups visible="yes" title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<sequences title=""/>
|
||||
<dictionaries title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
<memberdef>
|
||||
<inlineclasses title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<sequences title=""/>
|
||||
<dictionaries title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
</memberdef>
|
||||
<authorsection/>
|
||||
</file>
|
||||
|
||||
<!-- Layout definition for a group page -->
|
||||
<group>
|
||||
<briefdescription visible="yes"/>
|
||||
<groupgraph visible="$GROUP_GRAPHS"/>
|
||||
<memberdecl>
|
||||
<nestedgroups visible="yes" title=""/>
|
||||
<dirs visible="yes" title=""/>
|
||||
<files visible="yes" title=""/>
|
||||
<namespaces visible="yes" title=""/>
|
||||
<classes visible="yes" title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<sequences title=""/>
|
||||
<dictionaries title=""/>
|
||||
<enums title=""/>
|
||||
<enumvalues title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<signals title=""/>
|
||||
<publicslots title=""/>
|
||||
<protectedslots title=""/>
|
||||
<privateslots title=""/>
|
||||
<events title=""/>
|
||||
<properties title=""/>
|
||||
<friends title=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
<memberdef>
|
||||
<pagedocs/>
|
||||
<inlineclasses title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<sequences title=""/>
|
||||
<dictionaries title=""/>
|
||||
<enums title=""/>
|
||||
<enumvalues title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<signals title=""/>
|
||||
<publicslots title=""/>
|
||||
<protectedslots title=""/>
|
||||
<privateslots title=""/>
|
||||
<events title=""/>
|
||||
<properties title=""/>
|
||||
<friends title=""/>
|
||||
</memberdef>
|
||||
<authorsection visible="yes"/>
|
||||
</group>
|
||||
|
||||
<!-- Layout definition for a directory page -->
|
||||
<directory>
|
||||
<briefdescription visible="yes"/>
|
||||
<directorygraph visible="yes"/>
|
||||
<memberdecl>
|
||||
<dirs visible="yes"/>
|
||||
<files visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
</directory>
|
||||
</doxygenlayout>
|
||||
@ -0,0 +1,109 @@
|
||||
/**
|
||||
@mainpage Overview
|
||||
@anchor BackOff Algorithm
|
||||
@brief backoffAlgorithm Library
|
||||
|
||||
<p>
|
||||
A library that calculates the back-off period for a retry attempt using exponential back-off with jitter algorithm.
|
||||
This library uses the "Full Jitter" strategy for the exponential back-off with jitter algorithm.
|
||||
|
||||
More information about the algorithm can be seen in the [Exponential Backoff and Jitter](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/) AWS blog.
|
||||
|
||||
Exponential backoff with jitter is typically used when retrying a failed network
|
||||
connection or operation request with the server. An exponential backoff with jitter helps to
|
||||
mitigate failed network operations with servers, that are caused due to network congestion or high request load on
|
||||
the server, by spreading out retry requests across multiple devices attempting network operations.
|
||||
Besides, in an environment with poor connectivity, a client can get disconnected at any time.
|
||||
A backoff strategy helps the client to conserve battery by not repeatedly attempting reconnections when they are
|
||||
unlikely to succeed.
|
||||
|
||||
Before retrying the failed communication to the server, there is a delay period.
|
||||
In this delay period, the task that is retrying must sleep for some random amount
|
||||
of milliseconds between 0 and the lesser of the backoff window (related to the retry attempt)
|
||||
and a predefined maximum delay value. The backoff window is doubled with each retry
|
||||
attempt until the maximum delay value is reached.<br>
|
||||
|
||||
> sleep_ms = random_between( 0, min( 2<sup>attempts_count</sup> * base_ms, maximum_ms ) )
|
||||
|
||||
The library is written in C and designed to be compliant with ISO C90 and MISRA C:2012.
|
||||
|
||||
For a reference example of using the library, refer to the related README section in the repository [here](https://github.com/FreeRTOS/backoffAlgorithm#reference-example).
|
||||
|
||||
</p>
|
||||
|
||||
@section backoff_algorithm_memory_requirements Memory Requirements
|
||||
@brief Memory requirements of the backoffAlgorithm library.
|
||||
|
||||
@include{doc} size_table.md
|
||||
|
||||
@section backoff_algorithm_design Design
|
||||
@brief backoffAlgorithm Library Design
|
||||
|
||||
<h3>Memory Usage</h3>
|
||||
<p>
|
||||
All functions in the backoffAlgorithm library operate only on the buffer provided and use only
|
||||
local variables on the stack.
|
||||
</p>
|
||||
|
||||
<h3>Random Number Generation</h3>
|
||||
<p>
|
||||
The library takes a random number each time it calculates the backoff period value for the
|
||||
retry attempt. To avoid calculation of the same random numbers across your fleet of devices
|
||||
attempting retry of network operations, it is RECOMMENDED to generate the random number with
|
||||
a random number generator that is seeded with an entropy source unique to the device.
|
||||
</p>
|
||||
|
||||
<h3>Compliance & Coverage</h3>
|
||||
<p>
|
||||
The backoffAlgorithm library is designed to be compliant with ISO C90 and MISRA C:2012.
|
||||
All functions are written to have minimal complexity. Unit tests are written to cover
|
||||
every path of execution and achieve 100% branch coverage.
|
||||
</p>
|
||||
*/
|
||||
|
||||
/**
|
||||
@page backoff_algorithm_example Code Example for backoffAlgorithm API
|
||||
@brief Example POSIX application that retries DNS resolution operation with exponential backoff-and-jitter using the backoffAlgorithm library.
|
||||
|
||||
@include backoff_algorithm_posix.c
|
||||
*/
|
||||
|
||||
/**
|
||||
@page backoff_algorithm_functions Functions
|
||||
@brief Primary functions of the backoffAlgorithm library:<br><br>
|
||||
@subpage define_backoffalgorithm_initializeparams <br>
|
||||
@subpage define_backoffalgorithm_getnextbackoff <br>
|
||||
|
||||
<b>For a code example </b> of using backoffAlgorithm library for retrying operations with exponential back-off and jitter, refer to @ref backoff_algorithm_example.
|
||||
|
||||
@page define_backoffalgorithm_initializeparams BackoffAlgorithm_InitializeParams
|
||||
@snippet backoff_algorithm.h define_backoffalgorithm_initializeparams
|
||||
@copydoc BackoffAlgorithm_InitializeParams
|
||||
|
||||
From the @ref backoff_algorithm_example, following is the part relevant to the @ref BackoffAlgorithm_InitializeParams API.
|
||||
@snippet backoff_algorithm_posix.c code_example_backoffalgorithm_initializeparams
|
||||
|
||||
@page define_backoffalgorithm_getnextbackoff BackoffAlgorithm_GetNextBackoff
|
||||
@copydoc BackoffAlgorithm_GetNextBackoff
|
||||
|
||||
From the @ref backoff_algorithm_example, following is the part relevant to the @ref BackoffAlgorithm_GetNextBackoff API.
|
||||
@snippet backoff_algorithm_posix.c code_example_backoffalgorithm_getnextbackoff
|
||||
|
||||
*/
|
||||
|
||||
<!-- We do not use doxygen ALIASes here because there have been issues in the past versions with "^^" newlines within the alias definition. -->
|
||||
|
||||
/**
|
||||
@defgroup backoff_algorithm_struct_types Parameter Structure
|
||||
@brief Structure passed as parameter to [backoffAlgorithm library functions](@ref backoff_algorithm_functions)
|
||||
*/
|
||||
|
||||
/**
|
||||
@defgroup backoff_algorithm_enum_types Enumerated Types
|
||||
@brief Enumerated types of the backoffAlgorithm library
|
||||
*/
|
||||
|
||||
/**
|
||||
@defgroup backoff_algorithm_constants Constants
|
||||
@brief Constants defined in the backoffAlgorithm library
|
||||
*/
|
||||
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Stylesheet for Doxygen HTML output.
|
||||
*
|
||||
* This file defines styles for custom elements in the header/footer and
|
||||
* overrides some of the default Doxygen styles.
|
||||
*
|
||||
* Styles in this file do not affect the treeview sidebar.
|
||||
*/
|
||||
|
||||
/* Set the margins to place a small amount of whitespace on the left and right
|
||||
* side of the page. */
|
||||
div.contents {
|
||||
margin-left:4em;
|
||||
margin-right:4em;
|
||||
}
|
||||
|
||||
/* Justify text in paragraphs. */
|
||||
p {
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
/* Style of section headings. */
|
||||
h1 {
|
||||
border-bottom: 1px solid #879ECB;
|
||||
color: #354C7B;
|
||||
font-size: 160%;
|
||||
font-weight: normal;
|
||||
padding-bottom: 4px;
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
/* Style of subsection headings. */
|
||||
h2:not(.memtitle):not(.groupheader) {
|
||||
font-size: 125%;
|
||||
margin-bottom: 0px;
|
||||
margin-top: 16px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
/* Style of paragraphs immediately after subsection headings. */
|
||||
h2 + p {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
/* Style of subsection headings. */
|
||||
h3 {
|
||||
font-size: 100%;
|
||||
margin-bottom: 0px;
|
||||
margin-left: 2em;
|
||||
margin-right: 2em;
|
||||
}
|
||||
|
||||
/* Style of paragraphs immediately after subsubsection headings. */
|
||||
h3 + p {
|
||||
margin-top: 0px;
|
||||
margin-left: 2em;
|
||||
margin-right: 2em;
|
||||
}
|
||||
|
||||
/* Style of the prefix "AWS IoT Device SDK C" that appears in the header. */
|
||||
#csdkprefix {
|
||||
color: #757575;
|
||||
}
|
||||
|
||||
/* Style of the "Return to main page" link that appears in the header. */
|
||||
#returntomain {
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
/* Style of the dividers on Configuration Settings pages. */
|
||||
div.configpagedivider {
|
||||
margin-left: 0px !important;
|
||||
margin-right: 0px !important;
|
||||
margin-top: 20px !important;
|
||||
}
|
||||
|
||||
/* Style of configuration setting names. */
|
||||
dl.section.user ~ h1 {
|
||||
border-bottom: none;
|
||||
color: #000000;
|
||||
font-family: monospace, fixed;
|
||||
font-size: 16px;
|
||||
margin-bottom: 0px;
|
||||
margin-left: 2em;
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
/* Style of paragraphs on a configuration settings page. */
|
||||
dl.section.user ~ * {
|
||||
margin-bottom: 10px;
|
||||
margin-left: 4em;
|
||||
margin-right: 4em;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
/* Hide the configuration setting marker. */
|
||||
dl.section.user {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Overrides for code fragments and lines. */
|
||||
div.fragment {
|
||||
background: #ffffff;
|
||||
border: none;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
div.line {
|
||||
color: #3a3a3a;
|
||||
}
|
||||
|
||||
/* Overrides for code syntax highlighting colors. */
|
||||
span.comment {
|
||||
color: #008000;
|
||||
}
|
||||
|
||||
span.keyword, span.keywordtype, span.keywordflow {
|
||||
color: #0000ff;
|
||||
}
|
||||
|
||||
span.preprocessor {
|
||||
color: #50015a;
|
||||
}
|
||||
|
||||
span.stringliteral, span.charliteral {
|
||||
color: #800c0c;
|
||||
}
|
||||
|
||||
a.code, a.code:visited, a.line, a.line:visited {
|
||||
color: #496194;
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
api
|
||||
apis
|
||||
aws
|
||||
backoff
|
||||
backoff
|
||||
backoffalgorithm
|
||||
backoffalgorithmretriesexhausted
|
||||
backoffalgorithmrngfailure
|
||||
backoffalgorithmsuccess
|
||||
backoffbase
|
||||
br
|
||||
colspan
|
||||
com
|
||||
copydoc
|
||||
defgroup
|
||||
dns
|
||||
endif
|
||||
fd
|
||||
freertos
|
||||
gcc
|
||||
getaddrinfo
|
||||
github
|
||||
html
|
||||
https
|
||||
ifdef
|
||||
ifndef
|
||||
inc
|
||||
ingroup
|
||||
iot
|
||||
iso
|
||||
longjmp
|
||||
mainpage
|
||||
maxattempts
|
||||
maxbackoff
|
||||
maxretryattempts
|
||||
md
|
||||
min
|
||||
misra
|
||||
mit
|
||||
mockrng
|
||||
noninfringement
|
||||
os
|
||||
param
|
||||
pcontext
|
||||
pnextbackoff
|
||||
posix
|
||||
pretrycontext
|
||||
pretryparams
|
||||
prng
|
||||
rand
|
||||
randomvalue
|
||||
readme
|
||||
rm
|
||||
rng
|
||||
sdk
|
||||
spdx
|
||||
shouldn
|
||||
stderr
|
||||
sublicense
|
||||
tcp
|
||||
td
|
||||
toolchain
|
||||
tr
|
||||
trng
|
||||
usleep
|
||||
@ -0,0 +1,5 @@
|
||||
name : "backoffAlgorithm"
|
||||
version: "v1.3.0"
|
||||
description: |
|
||||
"Algorithm for calculating exponential backoff with jitter for network retry attempts.\n"
|
||||
license: "MIT"
|
||||
@ -0,0 +1,29 @@
|
||||
SPDXVersion: SPDX-2.2
|
||||
DataLicense: CC0-1.0
|
||||
SPDXID: SPDXRef-DOCUMENT
|
||||
DocumentName: backoffAlgorithm
|
||||
DocumentNamespace: https://github.com/FreeRTOS/backoffAlgorithm/blob/v1.3.0/sbom.spdx
|
||||
Creator: Amazon Web Services
|
||||
Created: 2022-10-14T15:39:49Z
|
||||
CreatorComment: NOASSERTION
|
||||
DocumentComment: NOASSERTION
|
||||
|
||||
PackageName: backoffAlgorithm
|
||||
SPDXID: SPDXRef-Package-backoffAlgorithm
|
||||
PackageVersion: v1.3.0
|
||||
PackageDownloadLocation: https://github.com/FreeRTOS/backoffAlgorithm/tree/v1.3.0
|
||||
PackageLicenseConcluded: MIT
|
||||
FilesAnalyzed: True
|
||||
PackageVerificationCode: 8cf87c7d09f62a054172b8f82227e3c116b08388
|
||||
PackageCopyrightText: NOASSERTION
|
||||
PackageSummary: NOASSERTION
|
||||
PackageDescription: "Algorithm for calculating exponential backoff with jitter for network retry attempts.\n"
|
||||
|
||||
|
||||
FileName: ./backoff_algorithm.c
|
||||
SPDXID: SPDXRef-File-backoff_algorithm.c
|
||||
FileChecksum: SHA1: ee94d75f7a99e11628734dd306e209913ea3058e
|
||||
LicenseConcluded: MIT
|
||||
FileCopyrightText: NOASSERTION
|
||||
FileComment: NOASSERTION
|
||||
|
||||
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* backoffAlgorithm v1.3.0
|
||||
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file backoff_algorithm.c
|
||||
* @brief Implementation of the backoff algorithm API for a "Full Jitter" exponential backoff
|
||||
* with jitter strategy.
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* Include API header. */
|
||||
#include "backoff_algorithm.h"
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BackoffAlgorithmStatus_t BackoffAlgorithm_GetNextBackoff( BackoffAlgorithmContext_t * pRetryContext,
|
||||
uint32_t randomValue,
|
||||
uint16_t * pNextBackOff )
|
||||
{
|
||||
BackoffAlgorithmStatus_t status = BackoffAlgorithmSuccess;
|
||||
|
||||
assert( pRetryContext != NULL );
|
||||
assert( pNextBackOff != NULL );
|
||||
|
||||
/* If maxRetryAttempts state of the context is set to the maximum, retry forever. */
|
||||
if( ( pRetryContext->maxRetryAttempts == BACKOFF_ALGORITHM_RETRY_FOREVER ) ||
|
||||
( pRetryContext->attemptsDone < pRetryContext->maxRetryAttempts ) )
|
||||
{
|
||||
/* The next backoff value is a random value between 0 and the maximum jitter value
|
||||
* for the retry attempt. */
|
||||
|
||||
/* Choose a random value for back-off time between 0 and the max jitter value. */
|
||||
*pNextBackOff = ( uint16_t ) ( randomValue % ( pRetryContext->nextJitterMax + ( uint32_t ) 1U ) );
|
||||
|
||||
/* Increment the retry attempt. */
|
||||
pRetryContext->attemptsDone++;
|
||||
|
||||
/* Double the max jitter value for the next retry attempt, only
|
||||
* if the new value will be less than the max backoff time value. */
|
||||
if( pRetryContext->nextJitterMax < ( pRetryContext->maxBackoffDelay / 2U ) )
|
||||
{
|
||||
pRetryContext->nextJitterMax += pRetryContext->nextJitterMax;
|
||||
}
|
||||
else
|
||||
{
|
||||
pRetryContext->nextJitterMax = pRetryContext->maxBackoffDelay;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* When max retry attempts are exhausted, let application know by
|
||||
* returning BackoffAlgorithmRetriesExhausted. Application may choose to
|
||||
* restart the retry process after calling BackoffAlgorithm_InitializeParams(). */
|
||||
status = BackoffAlgorithmRetriesExhausted;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void BackoffAlgorithm_InitializeParams( BackoffAlgorithmContext_t * pContext,
|
||||
uint16_t backOffBase,
|
||||
uint16_t maxBackOff,
|
||||
uint32_t maxAttempts )
|
||||
{
|
||||
assert( pContext != NULL );
|
||||
|
||||
/* Initialize the context with parameters used in calculating the backoff
|
||||
* value for the next retry attempt. */
|
||||
pContext->nextJitterMax = backOffBase;
|
||||
pContext->maxBackoffDelay = maxBackOff;
|
||||
pContext->maxRetryAttempts = maxAttempts;
|
||||
|
||||
/* The total number of retry attempts is zero at initialization. */
|
||||
pContext->attemptsDone = 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* backoffAlgorithm v1.3.0
|
||||
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file backoff_algorithm.h
|
||||
* @brief API for calculating backoff period for retry attempts using
|
||||
* exponential backoff with jitter algorithm.
|
||||
* This library represents the "Full Jitter" backoff strategy explained in the
|
||||
* following document.
|
||||
* https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BACKOFF_ALGORITHM_H_
|
||||
#define BACKOFF_ALGORITHM_H_
|
||||
|
||||
/* Standard include. */
|
||||
#include <stdint.h>
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/**
|
||||
* @ingroup backoff_algorithm_constants
|
||||
* @brief Constant to represent unlimited number of retry attempts.
|
||||
*/
|
||||
#define BACKOFF_ALGORITHM_RETRY_FOREVER ( UINT32_MAX )
|
||||
|
||||
/**
|
||||
* @ingroup backoff_algorithm_enum_types
|
||||
* @brief Status for @ref BackoffAlgorithm_GetNextBackoff.
|
||||
*/
|
||||
typedef enum BackoffAlgorithmStatus
|
||||
{
|
||||
BackoffAlgorithmSuccess = 0, /**< @brief The function successfully calculated the next back-off value. */
|
||||
BackoffAlgorithmRetriesExhausted /**< @brief The function exhausted all retry attempts. */
|
||||
} BackoffAlgorithmStatus_t;
|
||||
|
||||
/**
|
||||
* @ingroup backoff_algorithm_struct_types
|
||||
* @brief Represents parameters required for calculating the back-off delay for the
|
||||
* next retry attempt.
|
||||
*/
|
||||
typedef struct BackoffAlgorithmContext
|
||||
{
|
||||
/**
|
||||
* @brief The maximum backoff delay (in milliseconds) between consecutive retry attempts.
|
||||
*/
|
||||
uint16_t maxBackoffDelay;
|
||||
|
||||
/**
|
||||
* @brief The total number of retry attempts completed.
|
||||
* This value is incremented on every call to #BackoffAlgorithm_GetNextBackoff API.
|
||||
*/
|
||||
uint32_t attemptsDone;
|
||||
|
||||
/**
|
||||
* @brief The maximum backoff value (in milliseconds) for the next retry attempt.
|
||||
*/
|
||||
uint16_t nextJitterMax;
|
||||
|
||||
/**
|
||||
* @brief The maximum number of retry attempts.
|
||||
*/
|
||||
uint32_t maxRetryAttempts;
|
||||
} BackoffAlgorithmContext_t;
|
||||
|
||||
/**
|
||||
* @brief Initializes the context for using backoff algorithm. The parameters
|
||||
* are required for calculating the next retry backoff delay.
|
||||
* This function must be called by the application before the first new retry attempt.
|
||||
*
|
||||
* @param[out] pContext The context to initialize with parameters required
|
||||
* for the next backoff delay calculation function.
|
||||
* @param[in] maxBackOff The maximum backoff delay (in milliseconds) between
|
||||
* consecutive retry attempts.
|
||||
* @param[in] backOffBase The base value (in milliseconds) of backoff delay to
|
||||
* use in the exponential backoff and jitter model.
|
||||
* @param[in] maxAttempts The maximum number of retry attempts. Set the value to
|
||||
* #BACKOFF_ALGORITHM_RETRY_FOREVER to retry for ever.
|
||||
*/
|
||||
/* @[define_backoffalgorithm_initializeparams] */
|
||||
void BackoffAlgorithm_InitializeParams( BackoffAlgorithmContext_t * pContext,
|
||||
uint16_t backOffBase,
|
||||
uint16_t maxBackOff,
|
||||
uint32_t maxAttempts );
|
||||
/* @[define_backoffalgorithm_initializeparams] */
|
||||
|
||||
/**
|
||||
* @brief Simple exponential backoff and jitter function that provides the
|
||||
* delay value for the next retry attempt.
|
||||
* After a failure of an operation that needs to be retried, the application
|
||||
* should use this function to obtain the backoff delay value for the next retry,
|
||||
* and then wait for the backoff time period before retrying the operation.
|
||||
*
|
||||
* @param[in, out] pRetryContext Structure containing parameters for the next backoff
|
||||
* value calculation.
|
||||
* @param[in] randomValue The random value to use for calculation of the backoff period.
|
||||
* The random value should be in the range of [0, UINT32_MAX].
|
||||
* @param[out] pNextBackOff This will be populated with the backoff value (in milliseconds)
|
||||
* for the next retry attempt. The value does not exceed the maximum backoff delay
|
||||
* configured in the context.
|
||||
*
|
||||
* @note For generating a random number, it is recommended to use a Random Number Generator
|
||||
* that is seeded with a device-specific entropy source so that possibility of collisions
|
||||
* between multiple devices retrying the network operations can be mitigated.
|
||||
*
|
||||
* @return #BackoffAlgorithmSuccess after a successful sleep;
|
||||
* #BackoffAlgorithmRetriesExhausted when all attempts are exhausted.
|
||||
*/
|
||||
/* @[define_backoffalgorithm_getnextbackoff] */
|
||||
BackoffAlgorithmStatus_t BackoffAlgorithm_GetNextBackoff( BackoffAlgorithmContext_t * pRetryContext,
|
||||
uint32_t randomValue,
|
||||
uint16_t * pNextBackOff );
|
||||
/* @[define_backoffalgorithm_getnextbackoff] */
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#endif /* ifndef BACKOFF_ALGORITHM_H_ */
|
||||
@ -0,0 +1,37 @@
|
||||
#ifndef _STDINT_H
|
||||
#define _STDINT_H
|
||||
|
||||
/*******************************************************************************
|
||||
* THIS IS NOT A FULL stdint.h IMPLEMENTATION - It only contains the definitions
|
||||
* necessary to build the library code. It is provided to allow the library to
|
||||
* be built using compilers that do not provide their own stdint.h definition.
|
||||
*
|
||||
* To use this file:
|
||||
*
|
||||
* 1) Copy this file into a directory that is in your compiler's include path.
|
||||
* The directory must be part of the include path for system header file,
|
||||
* for example passed using gcc's "-I" or "-isystem" options.
|
||||
*
|
||||
* 2) Rename the copied file stdint.h.
|
||||
*
|
||||
*/
|
||||
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef long int32_t;
|
||||
typedef unsigned long uint32_t;
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
|
||||
#define INT8_MAX ( ( signed char ) 127 )
|
||||
#define UINT8_MAX ( ( unsigned char ) 255 )
|
||||
#define INT16_MAX ( ( short ) 32767 )
|
||||
#define UINT16_MAX ( ( unsigned short ) 65535 )
|
||||
#define INT32_MAX 2147483647L
|
||||
#define UINT32_MAX 4294967295UL
|
||||
#define INT64_MAX 9223372036854775807LL
|
||||
#define UINT64_MAX 18446744073709551615ULL
|
||||
|
||||
#endif /* _STDINT_H */
|
||||
@ -0,0 +1,102 @@
|
||||
cmake_minimum_required( VERSION 3.13.0 )
|
||||
project( "backoffAlgorithm unit test"
|
||||
VERSION 1.0.0
|
||||
LANGUAGES C )
|
||||
|
||||
# Allow the project to be organized into folders.
|
||||
set_property( GLOBAL PROPERTY USE_FOLDERS ON )
|
||||
|
||||
# Use C90.
|
||||
set( CMAKE_C_STANDARD 90 )
|
||||
set( CMAKE_C_STANDARD_REQUIRED ON )
|
||||
|
||||
# Do not allow in-source build.
|
||||
if( ${PROJECT_SOURCE_DIR} STREQUAL ${PROJECT_BINARY_DIR} )
|
||||
message( FATAL_ERROR "In-source build is not allowed. Please build in a separate directory, such as ${PROJECT_SOURCE_DIR}/build." )
|
||||
endif()
|
||||
|
||||
# Set global path variables.
|
||||
get_filename_component(__MODULE_ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE)
|
||||
set( MODULE_ROOT_DIR ${__MODULE_ROOT_DIR} CACHE INTERNAL "backoffAlgorithm source root." )
|
||||
set( UNIT_TEST_DIR ${MODULE_ROOT_DIR}/test/unit-test CACHE INTERNAL "backoffAlgorithm unit test directory." )
|
||||
set( UNITY_DIR ${UNIT_TEST_DIR}/Unity CACHE INTERNAL "Unity library source directory." )
|
||||
|
||||
# Configure options to always show in CMake GUI.
|
||||
option( BUILD_UNIT_TESTS
|
||||
"Set this to ON to build unit tests. This will clone the required Unity test framework submodule if it is not cloned already."
|
||||
OFF )
|
||||
|
||||
# Set output directories.
|
||||
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin )
|
||||
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib )
|
||||
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib )
|
||||
|
||||
# ================================ Coverity Analysis Configuration =================================
|
||||
|
||||
# Include filepaths for source and include.
|
||||
include( ${MODULE_ROOT_DIR}/backoffAlgorithmFilePaths.cmake )
|
||||
|
||||
# Target for Coverity analysis that builds the library.
|
||||
add_library( coverity_analysis
|
||||
${BACKOFF_ALGORITHM_SOURCES} )
|
||||
|
||||
# Backoff Algorithm library public include path.
|
||||
target_include_directories( coverity_analysis
|
||||
PUBLIC
|
||||
${BACKOFF_ALGORITHM_INCLUDE_PUBLIC_DIRS} )
|
||||
|
||||
# Disable logging/assert() calls when building the Coverity analysis target
|
||||
target_compile_options(coverity_analysis PUBLIC -DNDEBUG )
|
||||
|
||||
# ==================================== Unit Test Configuration ====================================
|
||||
|
||||
if(${BUILD_CODE_EXAMPLE})
|
||||
|
||||
# Target for code example binary.
|
||||
add_executable( code_example_posix
|
||||
${MODULE_ROOT_DIR}/docs/doxygen/code_examples/backoff_algorithm_posix.c )
|
||||
|
||||
target_link_libraries( code_example_posix coverity_analysis )
|
||||
|
||||
endif()
|
||||
|
||||
# ==================================== Unit Test Configuration ====================================
|
||||
|
||||
if(${BUILD_UNIT_TESTS})
|
||||
|
||||
# Include Unity build configuration.
|
||||
include( unit-test/unity_build.cmake )
|
||||
|
||||
# Check if the Unity source directory exists, and if not present, clone the submodule
|
||||
# if BUILD_CLONE_SUBMODULES configuration is enabled.
|
||||
if( NOT EXISTS ${UNITY_DIR}/src )
|
||||
# Attempt to clone Unity.
|
||||
clone_unity()
|
||||
endif()
|
||||
|
||||
# Add unit test and coverage configuration.
|
||||
|
||||
# Use CTest utility for managing test runs. This has to be added BEFORE
|
||||
# defining test targets with add_test()
|
||||
enable_testing()
|
||||
|
||||
# Add build targets for Unity and Unit, required for unit testing.
|
||||
add_unity_targets()
|
||||
|
||||
# Add function to enable Unity based tests and coverage.
|
||||
include( ${MODULE_ROOT_DIR}/tools/unity/create_test.cmake )
|
||||
|
||||
# Include build configuration for unit tests.
|
||||
add_subdirectory( unit-test )
|
||||
|
||||
# ==================================== Coverage Analysis configuration ============================
|
||||
|
||||
# Add a target for running coverage on tests.
|
||||
add_custom_target( coverage
|
||||
COMMAND ${CMAKE_COMMAND} -DUNITY_DIR=${UNITY_DIR}
|
||||
-P ${MODULE_ROOT_DIR}/tools/unity/coverage.cmake
|
||||
DEPENDS unity backoff_algorithm_utest
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
)
|
||||
|
||||
endif()
|
||||
@ -0,0 +1,71 @@
|
||||
# Include file path configuration for backoff algorithm library.
|
||||
include(${MODULE_ROOT_DIR}/backoffAlgorithmFilePaths.cmake)
|
||||
|
||||
project ("backoff algorithm unit test")
|
||||
cmake_minimum_required (VERSION 3.2.0)
|
||||
|
||||
# ==================== Define your project name (edit) ========================
|
||||
set(project_name "backoff_algorithm")
|
||||
|
||||
# ===================== Create your mock here (edit) ========================
|
||||
|
||||
# list the files to mock here
|
||||
list(APPEND mock_list
|
||||
""
|
||||
)
|
||||
|
||||
# list the directories your mocks need
|
||||
list(APPEND mock_include_list
|
||||
""
|
||||
)
|
||||
#list the definitions of your mocks to control what to be included
|
||||
list(APPEND mock_define_list
|
||||
""
|
||||
)
|
||||
|
||||
# ================= Create the library under test here (edit) ==================
|
||||
|
||||
# list the files you would like to test here
|
||||
list(APPEND real_source_files
|
||||
${BACKOFF_ALGORITHM_SOURCES}
|
||||
)
|
||||
# list the directories the module under test includes
|
||||
list(APPEND real_include_directories
|
||||
${BACKOFF_ALGORITHM_INCLUDE_PUBLIC_DIRS}
|
||||
)
|
||||
|
||||
# ===================== Create UnitTest Code here (edit) =====================
|
||||
|
||||
# list the directories your test needs to include
|
||||
list(APPEND test_include_directories
|
||||
${BACKOFF_ALGORITHM_INCLUDE_PUBLIC_DIRS}
|
||||
${CMAKE_CURRENT_LIST_DIR}
|
||||
)
|
||||
|
||||
# ============================= (end edit) ===================================
|
||||
|
||||
set(mock_name "${project_name}_mock")
|
||||
set(real_name "${project_name}_real")
|
||||
|
||||
create_real_library(${real_name}
|
||||
"${real_source_files}"
|
||||
"${real_include_directories}"
|
||||
""
|
||||
)
|
||||
|
||||
list(APPEND utest_link_list
|
||||
lib${real_name}.a
|
||||
)
|
||||
|
||||
list(APPEND utest_dep_list
|
||||
${real_name}
|
||||
)
|
||||
|
||||
set(utest_name "${project_name}_utest")
|
||||
set(utest_source "${project_name}_utest.c")
|
||||
create_test(${utest_name}
|
||||
${utest_source}
|
||||
"${utest_link_list}"
|
||||
"${utest_dep_list}"
|
||||
"${test_include_directories}"
|
||||
)
|
||||
@ -0,0 +1,350 @@
|
||||
/*
|
||||
* backoffAlgorithm v1.3.0
|
||||
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Unity include. */
|
||||
#include "unity.h"
|
||||
|
||||
/* Include utility for catching assert failures. */
|
||||
#include "catch_assert.h"
|
||||
|
||||
/* Backoff Algorithm library include */
|
||||
#include "backoff_algorithm.h"
|
||||
|
||||
#define TEST_BACKOFF_BASE_VALUE ( 1000 )
|
||||
#define TEST_BACKOFF_MAX_VALUE ( 10000 )
|
||||
#define TEST_MAX_ATTEMPTS ( 5 )
|
||||
/* Parameters to track the next max jitter or number of attempts done. */
|
||||
static BackoffAlgorithmContext_t retryParams;
|
||||
/* Return value of #BackoffAlgorithm_GetNextBackoff. */
|
||||
static BackoffAlgorithmStatus_t BackoffAlgorithmStatus;
|
||||
static uint16_t nextBackoff;
|
||||
static uint32_t testRandomVal;
|
||||
|
||||
/* ============================ UNITY FIXTURES ============================ */
|
||||
|
||||
/* Called before each test method. */
|
||||
void setUp()
|
||||
{
|
||||
/* Initialize context. */
|
||||
BackoffAlgorithm_InitializeParams( &retryParams,
|
||||
TEST_BACKOFF_BASE_VALUE,
|
||||
TEST_BACKOFF_MAX_VALUE,
|
||||
TEST_MAX_ATTEMPTS );
|
||||
}
|
||||
|
||||
/* Called after each test method. */
|
||||
void tearDown()
|
||||
{
|
||||
testRandomVal = 0;
|
||||
BackoffAlgorithmStatus = BackoffAlgorithmSuccess;
|
||||
nextBackoff = 0;
|
||||
}
|
||||
|
||||
/* Called at the beginning of the whole suite. */
|
||||
void suiteSetUp()
|
||||
{
|
||||
}
|
||||
|
||||
/* Called at the end of the whole suite. */
|
||||
int suiteTearDown( int numFailures )
|
||||
{
|
||||
return numFailures;
|
||||
}
|
||||
|
||||
/* ========================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Helper method to make assertions on data of the context object.
|
||||
*/
|
||||
static void verifyContextData( BackoffAlgorithmContext_t * pContext,
|
||||
uint32_t expectedAttemptsDone,
|
||||
uint16_t expectedNextJitterMax,
|
||||
uint16_t expectedMaxBackoff,
|
||||
uint32_t expectedMaxAttempts )
|
||||
{
|
||||
TEST_ASSERT_EQUAL( expectedNextJitterMax, pContext->nextJitterMax );
|
||||
TEST_ASSERT_EQUAL( expectedAttemptsDone, pContext->attemptsDone );
|
||||
TEST_ASSERT_EQUAL( expectedMaxAttempts, pContext->maxRetryAttempts );
|
||||
TEST_ASSERT_EQUAL( expectedMaxBackoff, pContext->maxBackoffDelay );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test that #BackoffAlgorithm_InitializeParams encounters an assert
|
||||
* failure when a NULL context parameter is passed.
|
||||
*/
|
||||
void test_BackoffAlgorithm_InitializeParams_Invalid_Context( void )
|
||||
{
|
||||
catch_assert( BackoffAlgorithm_InitializeParams( NULL /* Invalid context */,
|
||||
TEST_BACKOFF_BASE_VALUE,
|
||||
TEST_BACKOFF_MAX_VALUE,
|
||||
TEST_MAX_ATTEMPTS ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test that #BackoffAlgorithm_InitializeParams initializes the context
|
||||
* data as expected.
|
||||
*/
|
||||
void test_BackoffAlgorithm_InitializeParams_Sets_Jitter_Correctly( void )
|
||||
{
|
||||
BackoffAlgorithm_InitializeParams( &retryParams,
|
||||
TEST_BACKOFF_BASE_VALUE,
|
||||
TEST_BACKOFF_MAX_VALUE,
|
||||
TEST_MAX_ATTEMPTS );
|
||||
verifyContextData( &retryParams,
|
||||
0,
|
||||
TEST_BACKOFF_BASE_VALUE,
|
||||
TEST_BACKOFF_MAX_VALUE,
|
||||
TEST_MAX_ATTEMPTS );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test that #BackoffAlgorithm_GetNextBackoff returns the expected next back-off
|
||||
* value and updates the contents of the context as expected when the random value
|
||||
* generated is lower than the max jitter value for the retry attempts.
|
||||
*
|
||||
* This test assumes that the max jitter value has not reached the configured
|
||||
* maximum back-off value.
|
||||
*/
|
||||
void test_BackoffAlgorithm_GetNextBackoff_Success_RandVal_Less_Than_Jitter_Max( void )
|
||||
{
|
||||
int iter = 1;
|
||||
uint16_t expectedAttemptsDone = 0;
|
||||
uint16_t expectedNextJitterMax = TEST_BACKOFF_BASE_VALUE;
|
||||
uint16_t expectedNextBackoff = 0;
|
||||
|
||||
for( ; iter < 2; iter++ )
|
||||
{
|
||||
/* Set the random value as a value lower than
|
||||
* the jitter max value for the next retry attempt. */
|
||||
testRandomVal = retryParams.nextJitterMax / 2;
|
||||
|
||||
/* As the random value is less than the max jitter value, the expected
|
||||
* next backoff value should remain the same as the random value. */
|
||||
expectedNextBackoff = testRandomVal;
|
||||
|
||||
/* The jitter max value should double with the above call for use in next call. */
|
||||
expectedNextJitterMax *= 2;
|
||||
|
||||
/* The number of attempts should be updated by the above API call. */
|
||||
expectedAttemptsDone++;
|
||||
|
||||
TEST_ASSERT_LESS_THAN( TEST_BACKOFF_MAX_VALUE, expectedNextJitterMax );
|
||||
|
||||
/* Call the BackoffAlgorithm_GetNextBackoff API a couple times. */
|
||||
TEST_ASSERT_EQUAL( BackoffAlgorithmSuccess,
|
||||
BackoffAlgorithm_GetNextBackoff( &retryParams, testRandomVal, &nextBackoff ) );
|
||||
TEST_ASSERT_EQUAL( expectedNextBackoff, nextBackoff );
|
||||
|
||||
/* Verify that the context data for expected data after the API call. */
|
||||
verifyContextData( &retryParams,
|
||||
expectedAttemptsDone,
|
||||
expectedNextJitterMax,
|
||||
TEST_BACKOFF_MAX_VALUE,
|
||||
TEST_MAX_ATTEMPTS );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test that #BackoffAlgorithm_GetNextBackoff returns the expected next back-off
|
||||
* value and updates the contents of the context when the random value generated
|
||||
* is higher than the max jitter value for the retry attempts.
|
||||
*
|
||||
* This test assumes that the max jitter value has not reached the configured
|
||||
* maximum back-off value.
|
||||
*/
|
||||
void test_BackoffAlgorithm_GetNextBackoff_Success_RandVal_More_Than_Jitter_Max( void )
|
||||
{
|
||||
int iter = 1;
|
||||
uint16_t expectedAttemptsDone = 0;
|
||||
uint16_t expectedNextJitterMax = TEST_BACKOFF_BASE_VALUE;
|
||||
|
||||
for( ; iter < 2; iter++ )
|
||||
{
|
||||
/* Set the random value as a value greater than
|
||||
* the jitter max value for the next retry attempt. */
|
||||
testRandomVal = retryParams.nextJitterMax + 1;
|
||||
|
||||
/* The jitter max value should double with the above call for use in next call. */
|
||||
expectedNextJitterMax *= 2;
|
||||
TEST_ASSERT_LESS_THAN( TEST_BACKOFF_MAX_VALUE, expectedNextJitterMax );
|
||||
|
||||
/* The number of attempts should be updated by the above API call. */
|
||||
expectedAttemptsDone++;
|
||||
|
||||
/* As the random value is greater than the jitter max value, the expected
|
||||
* next backoff value should be truncated to a value within the jitter window
|
||||
* for the retry attempt. */
|
||||
uint16_t expectedNextBackoff = ( testRandomVal % ( retryParams.nextJitterMax + 1U ) );
|
||||
|
||||
/* Call the BackoffAlgorithm_GetNextBackoff API a couple times. */
|
||||
TEST_ASSERT_EQUAL( BackoffAlgorithmSuccess,
|
||||
BackoffAlgorithm_GetNextBackoff( &retryParams, testRandomVal, &nextBackoff ) );
|
||||
TEST_ASSERT_EQUAL( expectedNextBackoff, nextBackoff );
|
||||
|
||||
/* Verify that the context data for expected data after the API call. */
|
||||
verifyContextData( &retryParams,
|
||||
expectedAttemptsDone,
|
||||
expectedNextJitterMax,
|
||||
TEST_BACKOFF_MAX_VALUE,
|
||||
TEST_MAX_ATTEMPTS );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tests the #BackoffAlgorithm_GetNextBackoff API when the next back-off value
|
||||
* is requested for exhausted retry attempts.
|
||||
*/
|
||||
void test_BackoffAlgorithm_GetNextBackoff_Attempts_Exhausted()
|
||||
{
|
||||
/* Update the context data to represent that maximum configured number of
|
||||
* retry attempts have been completed. */
|
||||
retryParams.attemptsDone = TEST_MAX_ATTEMPTS;
|
||||
|
||||
/* Call the BackoffAlgorithm_GetNextBackoff API. */
|
||||
TEST_ASSERT_EQUAL( BackoffAlgorithmRetriesExhausted,
|
||||
BackoffAlgorithm_GetNextBackoff( &retryParams, testRandomVal, &nextBackoff ) );
|
||||
/* Make sure that the value of the output parameter has not changed. */
|
||||
TEST_ASSERT_EQUAL( 0, nextBackoff );
|
||||
|
||||
/* Make sure that the context data has not changed as the call to
|
||||
* BackoffAlgorithm_GetNextBackoff failed. */
|
||||
verifyContextData( &retryParams,
|
||||
TEST_MAX_ATTEMPTS /* Number of attempts shouldn't change */,
|
||||
TEST_BACKOFF_BASE_VALUE,
|
||||
TEST_BACKOFF_MAX_VALUE,
|
||||
TEST_MAX_ATTEMPTS );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tests that the #BackoffAlgorithm_GetNextBackoff API does not calculate a backoff period
|
||||
* beyond the configured maximum backoff period.
|
||||
*/
|
||||
void test_BackoffAlgorithm_GetNextBackoff_Returns_Cap_Backoff( void )
|
||||
{
|
||||
/* Initialize to 0 attempts, so the max value of next jitter will increase. */
|
||||
retryParams.attemptsDone = 0U;
|
||||
|
||||
/* Update the next jitter value to greater than half the maximum backoff so
|
||||
* that the BackoffAlgorithm_GetNextBackoff API updates the next jitter value to
|
||||
* the configured maximum backoff value. */
|
||||
retryParams.nextJitterMax = ( TEST_BACKOFF_MAX_VALUE / 2U ) + 1;
|
||||
|
||||
/* Set the random value equal to the current jitter max value.
|
||||
* Thus, the BackoffAlgorithm_GetNextBackoff API should return the random value as
|
||||
* the next back-off value. */
|
||||
testRandomVal = retryParams.nextJitterMax;
|
||||
uint16_t expectedBackoffVal = testRandomVal;
|
||||
|
||||
/* Call the BackoffAlgorithm_GetNextBackoff API. */
|
||||
TEST_ASSERT_EQUAL( BackoffAlgorithmSuccess,
|
||||
BackoffAlgorithm_GetNextBackoff( &retryParams, testRandomVal, &nextBackoff ) );
|
||||
/* Make sure that the expected value is returned for the next backoff. */
|
||||
TEST_ASSERT_EQUAL( expectedBackoffVal, nextBackoff );
|
||||
|
||||
/* Verify that the next jitter max value has been set to the cap back-off value
|
||||
* configured in the context. */
|
||||
verifyContextData( &retryParams,
|
||||
1,
|
||||
TEST_BACKOFF_MAX_VALUE /* New jitter max */,
|
||||
TEST_BACKOFF_MAX_VALUE,
|
||||
TEST_MAX_ATTEMPTS );
|
||||
|
||||
|
||||
/* Now, set the random value as the maximum back-off value to
|
||||
* expect that the next back-off value returned by the API is the maximum
|
||||
* back-off value.*/
|
||||
testRandomVal = TEST_BACKOFF_MAX_VALUE;
|
||||
|
||||
/* Call BackoffAlgorithm_GetNextBackoff API again to verify that it now returns the
|
||||
* cap value as the next back-off value. */
|
||||
TEST_ASSERT_EQUAL( BackoffAlgorithmSuccess,
|
||||
BackoffAlgorithm_GetNextBackoff( &retryParams, testRandomVal, &nextBackoff ) );
|
||||
/* Make sure that the capped backoff value is returned as the next backoff value . */
|
||||
TEST_ASSERT_EQUAL( TEST_BACKOFF_MAX_VALUE, nextBackoff );
|
||||
|
||||
/* Verify that the context data for expected data after the API call. */
|
||||
verifyContextData( &retryParams,
|
||||
2,
|
||||
TEST_BACKOFF_MAX_VALUE /* jitter max remains unchanged */,
|
||||
TEST_BACKOFF_MAX_VALUE,
|
||||
TEST_MAX_ATTEMPTS );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tests the #BackoffAlgorithm_GetNextBackoff API when the next jitter max value
|
||||
* is one lower than half of the maximum backoff value. This tests that the API does not
|
||||
* update the next jitter max to the maximum backoff value in this case.
|
||||
*/
|
||||
void test_BackoffAlgorithm_GetNextBackoff_NextJitterMax_Below_Cap_Backoff( void )
|
||||
{
|
||||
/* Initialize context.
|
||||
* Use the configuration constant of retrying forever to achieve branch coverage in tests
|
||||
* for the configuration. */
|
||||
BackoffAlgorithm_InitializeParams( &retryParams,
|
||||
TEST_BACKOFF_BASE_VALUE,
|
||||
TEST_BACKOFF_MAX_VALUE,
|
||||
BACKOFF_ALGORITHM_RETRY_FOREVER );
|
||||
|
||||
/* Initialize to 0 attempts, so the max value of next jitter will increase. */
|
||||
retryParams.attemptsDone = 0U;
|
||||
|
||||
/* Set the random value to zero to test that the BackoffAlgorithm_GetNextBackoff
|
||||
* API will return zero as the next back-off value.*/
|
||||
testRandomVal = 0;
|
||||
|
||||
/* Update the next jitter max value to one less than half of max backoff
|
||||
* to make sure that the BackoffAlgorithm_GetNextBackoff API does not update it
|
||||
* to the cap value in the call.*/
|
||||
retryParams.nextJitterMax = ( TEST_BACKOFF_MAX_VALUE / 2U ) - 1;
|
||||
|
||||
/* Call the BackoffAlgorithm_GetNextBackoff API. */
|
||||
TEST_ASSERT_EQUAL( BackoffAlgorithmSuccess,
|
||||
BackoffAlgorithm_GetNextBackoff( &retryParams, testRandomVal, &nextBackoff ) );
|
||||
/* Make sure that zero is returned as the next backoff value . */
|
||||
TEST_ASSERT_EQUAL( 0, nextBackoff );
|
||||
|
||||
/* Verify that the context data for expected data after the API call. */
|
||||
verifyContextData( &retryParams,
|
||||
1,
|
||||
TEST_BACKOFF_MAX_VALUE - 2U /* next jitter max value */,
|
||||
TEST_BACKOFF_MAX_VALUE,
|
||||
BACKOFF_ALGORITHM_RETRY_FOREVER );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tests that the #BackoffAlgorithm_GetNextBackoff API encounters assert failures
|
||||
* when called with invalid parameters.
|
||||
*/
|
||||
void test_BackoffAlgorithm_GetNextBackoff_Invalid_Params()
|
||||
{
|
||||
/* Invalid context. */
|
||||
catch_assert( BackoffAlgorithm_GetNextBackoff( NULL, testRandomVal, &nextBackoff ) );
|
||||
|
||||
/* Invalid output parameter for next back-off. */
|
||||
catch_assert( BackoffAlgorithm_GetNextBackoff( &retryParams, testRandomVal, NULL ) );
|
||||
}
|
||||
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* backoffAlgorithm v1.3.0
|
||||
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* How to catch an assert:
|
||||
* - save a jump buffer where execution will resume after the assert
|
||||
* - setup a handler for the abort signal, call longjmp within
|
||||
* - optional - close stderr ( fd 2 ) to discard the assert message
|
||||
*
|
||||
* Unity also does a longjmp within its TEST_ASSERT* macros,
|
||||
* so the macro below restores stderr and the prior abort handler
|
||||
* before calling the Unity macro.
|
||||
*/
|
||||
|
||||
#ifndef CATCH_ASSERT_H_
|
||||
#define CATCH_ASSERT_H_
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef CATCH_JMPBUF
|
||||
#define CATCH_JMPBUF waypoint_
|
||||
#endif
|
||||
|
||||
jmp_buf CATCH_JMPBUF;
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
static void catchHandler_( int signal )
|
||||
{
|
||||
longjmp( CATCH_JMPBUF, signal );
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#define catch_assert( x ) \
|
||||
do { \
|
||||
int try = 0, catch = 0; \
|
||||
int saveFd = dup( 2 ); \
|
||||
struct sigaction sa = { 0 }, saveSa; \
|
||||
sa.sa_handler = catchHandler_; \
|
||||
sigaction( SIGABRT, &sa, &saveSa ); \
|
||||
close( 2 ); \
|
||||
if( setjmp( CATCH_JMPBUF ) == 0 ) \
|
||||
{ \
|
||||
try++; \
|
||||
x; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
catch++; \
|
||||
} \
|
||||
sigaction( SIGABRT, &saveSa, NULL ); \
|
||||
dup2( saveFd, 2 ); \
|
||||
close( saveFd ); \
|
||||
TEST_ASSERT_EQUAL( try, catch ); \
|
||||
} while( 0 )
|
||||
|
||||
#endif /* ifndef CATCH_ASSERT_H_ */
|
||||
@ -0,0 +1,38 @@
|
||||
# Macro utility to clone the Unity submodule.
|
||||
macro( clone_unity )
|
||||
find_package( Git REQUIRED )
|
||||
message( "Cloning submodule Unity." )
|
||||
execute_process( COMMAND rm -rf ${UNITY_DIR}
|
||||
COMMAND ${GIT_EXECUTABLE} submodule update --checkout --init --recursive ${UNITY_DIR}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
RESULT_VARIABLE UNITY_CLONE_RESULT )
|
||||
|
||||
if( NOT ${UNITY_CLONE_RESULT} STREQUAL "0" )
|
||||
message( FATAL_ERROR "Failed to clone Unity submodule." )
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Macro utility to add library targets for Unity and Unity to build configuration.
|
||||
macro( add_unity_targets )
|
||||
# Build Configuration for Unity and Unity libraries.
|
||||
list( APPEND UNITY_INCLUDE_DIRS
|
||||
"${UNITY_DIR}/src/"
|
||||
"${UNITY_DIR}/extras/fixture/src"
|
||||
"${UNITY_DIR}/extras/memory/src"
|
||||
)
|
||||
|
||||
add_library( unity STATIC
|
||||
"${UNITY_DIR}/src/unity.c"
|
||||
"${UNITY_DIR}/extras/fixture/src/unity_fixture.c"
|
||||
"${UNITY_DIR}/extras/memory/src/unity_memory.c"
|
||||
)
|
||||
|
||||
set_target_properties( unity PROPERTIES
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
)
|
||||
|
||||
target_include_directories( unity PUBLIC
|
||||
${UNITY_INCLUDE_DIRS}
|
||||
)
|
||||
endmacro()
|
||||
@ -0,0 +1,79 @@
|
||||
# Static code analysis for backoffAlgorithm library
|
||||
This directory is made for the purpose of statically testing the MISRA C:2012 compliance of backoffAlgorithm using
|
||||
[Synopsys Coverity](https://www.synopsys.com/software-integrity/security-testing/static-analysis-sast.html) static analysis tool.
|
||||
To that end, this directory provides a [configuration file](https://github.com/FreeRTOS/backoffAlgorithm/blob/main/tools/coverity/misra.config) to use when
|
||||
building a binary for the tool to analyze.
|
||||
|
||||
> **Note**
|
||||
For generating the report as outlined below, we have used Coverity version 2018.09.
|
||||
|
||||
For details regarding the suppressed violations in the report (which can be generated using the instructions described below), please
|
||||
see the [MISRA.md](https://github.com/FreeRTOS/backoffAlgorithm/blob/main/MISRA.md) file.
|
||||
|
||||
## Getting Started
|
||||
### Prerequisites
|
||||
You can run this on a platform supported by Coverity. The list and other details can be found [here](https://sig-docs.synopsys.com/polaris/topics/c_coverity-compatible-platforms.html).
|
||||
To compile and run the Coverity target successfully, you must have the following:
|
||||
|
||||
1. CMake version > 3.13.0 (You can check whether you have this by typing `cmake --version`)
|
||||
2. GCC compiler
|
||||
- You can see the downloading and installation instructions [here](https://gcc.gnu.org/install/).
|
||||
3. Download the repo and include the submodules using the following commands.
|
||||
- `git clone --recurse-submodules git@github.com:FreeRTOS/backoffAlgorithm.git ./backoffAlgorithm`
|
||||
- `cd ./backoffAlgorithm`
|
||||
- `git submodule update --checkout --init --recursive`
|
||||
|
||||
### To build and run coverity:
|
||||
Go to the root directory of the library and run the following commands in terminal:
|
||||
1. Update the compiler configuration in Coverity
|
||||
~~~
|
||||
cov-configure --force --compiler cc --comptype gcc
|
||||
~~~
|
||||
2. Create the build files using CMake in a `build` directory
|
||||
~~~
|
||||
cmake -B build -S test
|
||||
~~~
|
||||
3. Go to the build directory and copy the coverity configuration file
|
||||
~~~
|
||||
cd build/
|
||||
~~~
|
||||
4. Build the static analysis target
|
||||
~~~
|
||||
cov-build --emit-complementary-info --dir cov-out make coverity_analysis
|
||||
~~~
|
||||
5. Go to the Coverity output directory (`cov-out`) and begin Coverity static analysis
|
||||
~~~
|
||||
cd cov-out/
|
||||
cov-analyze --dir . --coding-standard-config ../../tools/coverity/misra.config --tu-pattern "file('.*/source/.*')"
|
||||
~~~
|
||||
6. Format the errors in HTML format so that it is more readable while removing the test and build directory from the report
|
||||
~~~
|
||||
cov-format-errors --dir . --file "source" --exclude-files '(/build/|/test/)' --html-output html-out;
|
||||
~~~
|
||||
7. Format the errors in JSON format to perform a jq query to get a simplified list of any exceptions.
|
||||
NOTE: A blank output means there are no defects that aren't being suppressed by the config or inline comments.
|
||||
~~~
|
||||
cov-format-errors --dir . --file "source" --exclude-files '(/build/|/test/)' --json-output-v2 defects.json;
|
||||
echo -e "\n-------------------------Non-Suppresed Deviations, if any, Listed Below-------------------------\n";
|
||||
jq '.issues[] | .events[] | .eventTag ' defects.json | sort | uniq -c | sort -nr;
|
||||
echo -e "\n-------------------------Non-Suppresed Deviations, if any, Listed Above-------------------------\n";
|
||||
~~~
|
||||
|
||||
For your convenience the commands above are below to be copy/pasted into a UNIX command friendly terminal.
|
||||
~~~
|
||||
cov-configure --force --compiler cc --comptype gcc;
|
||||
cmake -B build -S test;
|
||||
cd build/;
|
||||
cov-build --emit-complementary-info --dir cov-out make coverity_analysis;
|
||||
cd cov-out/
|
||||
cov-analyze --dir . --coding-standard-config ../../tools/coverity/misra.config;
|
||||
cov-format-errors --dir . --file "source" --exclude-files '(/build/|/test/)' --html-output html-out;
|
||||
cov-format-errors --dir . --file "source" --exclude-files '(/build/|/test/)' --json-output-v2 defects.json;
|
||||
echo -e "\n-------------------------Non-Suppresed Deviations, if any, Listed Below-------------------------\n";
|
||||
jq '.issues[] | .events[] | .eventTag ' defects.json | sort | uniq -c | sort -nr;
|
||||
echo -e "\n-------------------------Non-Suppresed Deviations, if any, Listed Above-------------------------\n";
|
||||
cd ../../;
|
||||
~~~
|
||||
|
||||
You should now have the HTML formatted violations list in a directory named `build/cov-out/html-output`.
|
||||
With the current configuration and the provided project, you should not see any deviations.
|
||||
@ -0,0 +1,26 @@
|
||||
// MISRA C-2012 Rules
|
||||
|
||||
{
|
||||
version : "2.0",
|
||||
standard : "c2012",
|
||||
title: "Coverity MISRA Configuration",
|
||||
deviations : [
|
||||
// Disable the following rules.
|
||||
{
|
||||
deviation: "Directive 4.9",
|
||||
reason: "Allow inclusion of function like macros. Logging is done using function like macros."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 2.4",
|
||||
reason: "Allow unused tags. Some compilers warn if types are not tagged."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 3.1",
|
||||
reason: "Allow nested comments. Documentation blocks contain comments for example code."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 8.7",
|
||||
reason: "API functions are not used by library. They must be externally visible in order to be used by the application."
|
||||
},
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,70 @@
|
||||
# Taken from amazon-freertos repository
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
set(BINARY_DIR ${CMAKE_BINARY_DIR})
|
||||
# reset coverage counters
|
||||
execute_process(
|
||||
COMMAND lcov --directory ${CMAKE_BINARY_DIR}
|
||||
--base-directory ${CMAKE_BINARY_DIR}
|
||||
--zerocounters
|
||||
|
||||
COMMAND mkdir -p ${CMAKE_BINARY_DIR}/coverage
|
||||
)
|
||||
# make the initial/baseline capture a zeroed out files
|
||||
execute_process( COMMAND lcov --directory ${CMAKE_BINARY_DIR}
|
||||
--base-directory ${CMAKE_BINARY_DIR}
|
||||
--initial
|
||||
--capture
|
||||
--rc lcov_branch_coverage=1
|
||||
--rc genhtml_branch_coverage=1
|
||||
--output-file=${CMAKE_BINARY_DIR}/base_coverage.info
|
||||
)
|
||||
file(GLOB files "${CMAKE_BINARY_DIR}/bin/tests/*")
|
||||
|
||||
set(REPORT_FILE ${CMAKE_BINARY_DIR}/utest_report.txt)
|
||||
file(WRITE ${REPORT_FILE} "")
|
||||
# execute all files in bin directory, gathering the output to show it in CI
|
||||
foreach(testname ${files})
|
||||
get_filename_component(test
|
||||
${testname}
|
||||
NAME_WLE
|
||||
)
|
||||
message("Running ${testname}")
|
||||
execute_process(COMMAND ${testname} OUTPUT_FILE ${CMAKE_BINARY_DIR}/${test}_out.txt)
|
||||
|
||||
file(READ ${CMAKE_BINARY_DIR}/${test}_out.txt CONTENTS)
|
||||
file(APPEND ${REPORT_FILE} "${CONTENTS}")
|
||||
endforeach()
|
||||
|
||||
# generate Junit style xml output
|
||||
execute_process(COMMAND ruby
|
||||
${UNITY_DIR}/auto/parse_output.rb
|
||||
-xml ${REPORT_FILE}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
)
|
||||
|
||||
# capture data after running the tests
|
||||
execute_process(
|
||||
COMMAND lcov --capture
|
||||
--rc lcov_branch_coverage=1
|
||||
--rc genhtml_branch_coverage=1
|
||||
--base-directory ${CMAKE_BINARY_DIR}
|
||||
--directory ${CMAKE_BINARY_DIR}
|
||||
--output-file ${CMAKE_BINARY_DIR}/second_coverage.info
|
||||
)
|
||||
|
||||
# combile baseline results (zeros) with the one after running the tests
|
||||
execute_process(
|
||||
COMMAND lcov --base-directory ${CMAKE_BINARY_DIR}
|
||||
--directory ${CMAKE_BINARY_DIR}
|
||||
--add-tracefile ${CMAKE_BINARY_DIR}/base_coverage.info
|
||||
--add-tracefile ${CMAKE_BINARY_DIR}/second_coverage.info
|
||||
--output-file ${CMAKE_BINARY_DIR}/coverage.info
|
||||
--no-external
|
||||
--rc lcov_branch_coverage=1
|
||||
)
|
||||
execute_process(
|
||||
COMMAND genhtml --rc lcov_branch_coverage=1
|
||||
--branch-coverage
|
||||
--output-directory ${CMAKE_BINARY_DIR}/coverage
|
||||
${CMAKE_BINARY_DIR}/coverage.info
|
||||
)
|
||||
@ -0,0 +1,73 @@
|
||||
# Taken from amazon-freertos repository
|
||||
|
||||
#function to create the test executable
|
||||
function(create_test test_name
|
||||
test_src
|
||||
link_list
|
||||
dep_list
|
||||
include_list)
|
||||
include (CTest)
|
||||
get_filename_component(test_src_absolute ${test_src} ABSOLUTE)
|
||||
add_custom_command(OUTPUT ${test_name}_runner.c
|
||||
COMMAND ruby
|
||||
${UNITY_DIR}/auto/generate_test_runner.rb
|
||||
${MODULE_ROOT_DIR}/tools/unity/project.yml
|
||||
${test_src_absolute}
|
||||
${test_name}_runner.c
|
||||
DEPENDS ${test_src}
|
||||
)
|
||||
add_executable(${test_name} ${test_src} ${test_name}_runner.c)
|
||||
set_target_properties(${test_name} PROPERTIES
|
||||
COMPILE_FLAG "-O0 -ggdb"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/tests"
|
||||
INSTALL_RPATH_USE_LINK_PATH TRUE
|
||||
LINK_FLAGS " \
|
||||
-Wl,-rpath,${CMAKE_BINARY_DIR}/lib \
|
||||
-Wl,-rpath,${CMAKE_CURRENT_BINARY_DIR}/lib"
|
||||
)
|
||||
target_include_directories(${test_name} PUBLIC
|
||||
${include_list}
|
||||
)
|
||||
|
||||
target_link_directories(${test_name} PUBLIC
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
# link all libraries sent through parameters
|
||||
foreach(link IN LISTS link_list)
|
||||
target_link_libraries(${test_name} ${link})
|
||||
endforeach()
|
||||
|
||||
# add dependency to all the dep_list parameter
|
||||
foreach(dependency IN LISTS dep_list)
|
||||
add_dependencies(${test_name} ${dependency})
|
||||
target_link_libraries(${test_name} ${dependency})
|
||||
endforeach()
|
||||
target_link_libraries(${test_name} -lgcov unity)
|
||||
target_link_directories(${test_name} PUBLIC
|
||||
${CMAKE_CURRENT_BINARY_DIR}/lib
|
||||
)
|
||||
add_test(NAME ${test_name}
|
||||
COMMAND ${CMAKE_BINARY_DIR}/bin/tests/${test_name}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
)
|
||||
endfunction()
|
||||
|
||||
function(create_real_library target
|
||||
src_file
|
||||
real_include_list)
|
||||
add_library(${target} STATIC
|
||||
${src_file}
|
||||
)
|
||||
target_include_directories(${target} PUBLIC
|
||||
${real_include_list}
|
||||
)
|
||||
set_target_properties(${target} PROPERTIES
|
||||
COMPILE_FLAGS "-Wextra -Wpedantic \
|
||||
-fprofile-arcs -ftest-coverage -fprofile-generate \
|
||||
-Wno-unused-but-set-variable"
|
||||
LINK_FLAGS "-fprofile-arcs -ftest-coverage \
|
||||
-fprofile-generate "
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib
|
||||
)
|
||||
endfunction()
|
||||
@ -0,0 +1,12 @@
|
||||
:unity:
|
||||
:when_no_prototypes: :warn
|
||||
:enforce_strict_ordering: TRUE
|
||||
:treat_as:
|
||||
uint8: HEX8
|
||||
uint16: HEX16
|
||||
uint32: UINT32
|
||||
int8: INT8
|
||||
bool: UINT8
|
||||
:treat_externs: :exclude
|
||||
:weak: __attribute__((weak))
|
||||
:treat_externs: :include
|
||||
@ -0,0 +1,5 @@
|
||||
[{000214A0-0000-0000-C000-000000000046}]
|
||||
Prop3=19,11
|
||||
[InternetShortcut]
|
||||
IDList=
|
||||
URL=https://www.freertos.org/logging.html
|
||||
52
kernel/FreeRTOS-Plus/Source/Utilities/logging/logging.h
Normal file
52
kernel/FreeRTOS-Plus/Source/Utilities/logging/logging.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* FreeRTOS V202212.01
|
||||
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DEMO_LOGGING_H
|
||||
#define DEMO_LOGGING_H
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
/*
|
||||
* Initialize a logging system that can be used from FreeRTOS tasks and Win32
|
||||
* threads. Do not call printf() directly while the scheduler is running.
|
||||
*
|
||||
* Set xLogToStdout, xLogToFile and xLogToUDP to either pdTRUE or pdFALSE to
|
||||
* lot to stdout, a disk file and a UDP port respectively.
|
||||
*
|
||||
* If xLogToUDP is pdTRUE then ulRemoteIPAddress and usRemotePort must be set
|
||||
* to the IP address and port number to which UDP log messages will be sent.
|
||||
*/
|
||||
void vLoggingInit( BaseType_t xLogToStdout,
|
||||
BaseType_t xLogToFile,
|
||||
BaseType_t xLogToUDP,
|
||||
uint32_t ulRemoteIPAddress,
|
||||
uint16_t usRemotePort );
|
||||
|
||||
void vPlatformInitLogging(void);
|
||||
|
||||
void vLoggingPrintf(const char* pcFormat, ...);
|
||||
|
||||
#endif /* DEMO_LOGGING_H */
|
||||
113
kernel/FreeRTOS-Plus/Source/Utilities/logging/logging_levels.h
Normal file
113
kernel/FreeRTOS-Plus/Source/Utilities/logging/logging_levels.h
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* FreeRTOS V202212.01
|
||||
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://aws.amazon.com/freertos
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file logging_levels.h
|
||||
* @brief Defines the configuration constants for all logging verbosity levels.
|
||||
*/
|
||||
|
||||
#ifndef LOGGING_LEVELS_H
|
||||
#define LOGGING_LEVELS_H
|
||||
|
||||
/**
|
||||
* @constantspage{logging,logging library}
|
||||
*
|
||||
* @section logging_constants_levels Log levels
|
||||
* @brief Log levels for the libraries in this SDK.
|
||||
*
|
||||
* Each library should specify a log level by setting @ref LIBRARY_LOG_LEVEL.
|
||||
* All log messages with a level at or below the specified level will be printed
|
||||
* for that library.
|
||||
*
|
||||
* Currently, there are 4 log levels. In the order of lowest to highest, they are:
|
||||
* - #LOG_NONE <br>
|
||||
* @copybrief LOG_NONE
|
||||
* - #LOG_ERROR <br>
|
||||
* @copybrief LOG_ERROR
|
||||
* - #LOG_WARN <br>
|
||||
* @copybrief LOG_WARN
|
||||
* - #LOG_INFO <br>
|
||||
* @copybrief LOG_INFO
|
||||
* - #LOG_DEBUG <br>
|
||||
* @copybrief LOG_DEBUG
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief No log messages.
|
||||
*
|
||||
* When @ref LIBRARY_LOG_LEVEL is #LOG_NONE, logging is disabled and no
|
||||
* logging messages are printed.
|
||||
*/
|
||||
#define LOG_NONE 0
|
||||
|
||||
/**
|
||||
* @brief Represents erroneous application state or event.
|
||||
*
|
||||
* These messages describe the situations when a library encounters an error from
|
||||
* which it cannot recover.
|
||||
*
|
||||
* These messages are printed when @ref LIBRARY_LOG_LEVEL is defined as either
|
||||
* of #LOG_ERROR, #LOG_WARN, #LOG_INFO or #LOG_DEBUG.
|
||||
*/
|
||||
#define LOG_ERROR 1
|
||||
|
||||
/**
|
||||
* @brief Message about an abnormal event.
|
||||
*
|
||||
* These messages describe the situations when a library encounters
|
||||
* abnormal event that may be indicative of an error. Libraries continue
|
||||
* execution after logging a warning.
|
||||
*
|
||||
* These messages are printed when @ref LIBRARY_LOG_LEVEL is defined as either
|
||||
* of #LOG_WARN, #LOG_INFO or #LOG_DEBUG.
|
||||
*/
|
||||
#define LOG_WARN 2
|
||||
|
||||
/**
|
||||
* @brief A helpful, informational message.
|
||||
*
|
||||
* These messages describe normal execution of a library. They provide
|
||||
* the progress of the program at a coarse-grained level.
|
||||
*
|
||||
* These messages are printed when @ref LIBRARY_LOG_LEVEL is defined as either
|
||||
* of #LOG_INFO or #LOG_DEBUG.
|
||||
*/
|
||||
#define LOG_INFO 3
|
||||
|
||||
/**
|
||||
* @brief Detailed and excessive debug information.
|
||||
*
|
||||
* Debug log messages are used to provide the
|
||||
* progress of the program at a fine-grained level. These are mostly used
|
||||
* for debugging and may contain excessive information such as internal
|
||||
* variables, buffers, or other specific information.
|
||||
*
|
||||
* These messages are only printed when @ref LIBRARY_LOG_LEVEL is defined as
|
||||
* #LOG_DEBUG.
|
||||
*/
|
||||
#define LOG_DEBUG 4
|
||||
|
||||
#endif /* ifndef LOGGING_LEVELS_H */
|
||||
132
kernel/FreeRTOS-Plus/Source/Utilities/logging/logging_stack.h
Normal file
132
kernel/FreeRTOS-Plus/Source/Utilities/logging/logging_stack.h
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* FreeRTOS V202212.01
|
||||
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file logging_stack.h
|
||||
* @brief Utility header file that exposes macros for configuring logging implementation of logging macros (LogError, LogWarn, LogInfo, LogDebug).
|
||||
*/
|
||||
|
||||
#ifndef LOGGING_STACK_H
|
||||
#define LOGGING_STACK_H
|
||||
|
||||
/* Include header for logging level macros. */
|
||||
#include "logging_levels.h"
|
||||
|
||||
#include "logging.h"
|
||||
|
||||
/* Standard Include. */
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief The name of the library or demo to add as metadata in log messages
|
||||
* from the library or demo.
|
||||
*
|
||||
* This metadata aids in identifying the module source of log messages.
|
||||
* The metadata is logged in the format `[ <LIBRARY-NAME> ]` as a prefix to the
|
||||
* log messages.
|
||||
* Refer to #LOG_METADATA_FORMAT for the complete format of the metadata prefix in
|
||||
* log messages.
|
||||
*/
|
||||
/* Check if LIBRARY_LOG_NAME macro has been defined. */
|
||||
#if !defined( LIBRARY_LOG_NAME )
|
||||
#error "Please define LIBRARY_LOG_NAME for the library."
|
||||
#endif
|
||||
|
||||
/* Metadata information to prepend to every log message. */
|
||||
#ifndef LOG_METADATA_FORMAT
|
||||
#define LOG_METADATA_FORMAT "[%s:%d] " /**< @brief Format of metadata prefix in log messages. */
|
||||
#endif
|
||||
|
||||
#ifndef LOG_METADATA_ARGS
|
||||
#define LOG_METADATA_ARGS __FUNCTION__, __LINE__ /**< @brief Arguments into the metadata logging prefix format. */
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Common macro that maps all the logging interfaces,
|
||||
* (#LogDebug, #LogInfo, #LogWarn, #LogError) to the platform-specific logging
|
||||
* function.
|
||||
*
|
||||
* @note The default definition of this macro generates logging via a printf-like
|
||||
* vLoggingPrintf function.
|
||||
*/
|
||||
#ifndef SdkLog
|
||||
#define SdkLog( message ) vLoggingPrintf message
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Disable definition of logging interface macros when generating doxygen output,
|
||||
* to avoid conflict with documentation of macros at the end of the file.
|
||||
*/
|
||||
/* Check that LIBRARY_LOG_LEVEL is defined and has a valid value. */
|
||||
#if !defined( LIBRARY_LOG_LEVEL ) || \
|
||||
( ( LIBRARY_LOG_LEVEL != LOG_NONE ) && \
|
||||
( LIBRARY_LOG_LEVEL != LOG_ERROR ) && \
|
||||
( LIBRARY_LOG_LEVEL != LOG_WARN ) && \
|
||||
( LIBRARY_LOG_LEVEL != LOG_INFO ) && \
|
||||
( LIBRARY_LOG_LEVEL != LOG_DEBUG ) )
|
||||
#error "Please define LIBRARY_LOG_LEVEL as either LOG_NONE, LOG_ERROR, LOG_WARN, LOG_INFO, or LOG_DEBUG."
|
||||
#else
|
||||
#if LIBRARY_LOG_LEVEL == LOG_DEBUG
|
||||
/* All log level messages will logged. */
|
||||
#define LogError( message ) SdkLog( ( "[ERROR] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) )
|
||||
#define LogWarn( message ) SdkLog( ( "[WARN] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) )
|
||||
#define LogInfo( message ) SdkLog( ( "[INFO] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) )
|
||||
#define LogDebug( message ) SdkLog( ( "[DEBUG] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) )
|
||||
|
||||
#elif LIBRARY_LOG_LEVEL == LOG_INFO
|
||||
/* Only INFO, WARNING and ERROR messages will be logged. */
|
||||
#define LogError( message ) SdkLog( ( "[ERROR] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) )
|
||||
#define LogWarn( message ) SdkLog( ( "[WARN] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) )
|
||||
#define LogInfo( message ) SdkLog( ( "[INFO] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) )
|
||||
#define LogDebug( message )
|
||||
|
||||
#elif LIBRARY_LOG_LEVEL == LOG_WARN
|
||||
/* Only WARNING and ERROR messages will be logged.*/
|
||||
#define LogError( message ) SdkLog( ( "[ERROR] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) )
|
||||
#define LogWarn( message ) SdkLog( ( "[WARN] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) )
|
||||
#define LogInfo( message )
|
||||
#define LogDebug( message )
|
||||
|
||||
#elif LIBRARY_LOG_LEVEL == LOG_ERROR
|
||||
/* Only ERROR messages will be logged. */
|
||||
#define LogError( message ) SdkLog( ( "[ERROR] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) )
|
||||
#define LogWarn( message )
|
||||
#define LogInfo( message )
|
||||
#define LogDebug( message )
|
||||
|
||||
#else /* if LIBRARY_LOG_LEVEL == LOG_ERROR */
|
||||
|
||||
#define LogError( message )
|
||||
#define LogWarn( message )
|
||||
#define LogInfo( message )
|
||||
#define LogDebug( message )
|
||||
|
||||
#endif /* if LIBRARY_LOG_LEVEL == LOG_ERROR */
|
||||
#endif /* if !defined( LIBRARY_LOG_LEVEL ) || ( ( LIBRARY_LOG_LEVEL != LOG_NONE ) && ( LIBRARY_LOG_LEVEL != LOG_ERROR ) && ( LIBRARY_LOG_LEVEL != LOG_WARN ) && ( LIBRARY_LOG_LEVEL != LOG_INFO ) && ( LIBRARY_LOG_LEVEL != LOG_DEBUG ) ) */
|
||||
|
||||
#endif /* ifndef LOGGING_STACK_H */
|
||||
14
kernel/FreeRTOS-Plus/Source/Utilities/readme.txt
Normal file
14
kernel/FreeRTOS-Plus/Source/Utilities/readme.txt
Normal file
@ -0,0 +1,14 @@
|
||||
Directories:
|
||||
|
||||
+ Utilities/backoff_algorithm contains a utility that calculates an
|
||||
exponential back off time, with some jitter. It is used to ensure fleets of
|
||||
IoT devices that become disconnected don't all try and reconnect at the same
|
||||
time.
|
||||
|
||||
+ Utilities/logging contains header files for use with the core libraries logging
|
||||
macros. See https://www.FreeRTOS.org/logging.html.
|
||||
|
||||
+ Utililties/mbedtls_freertos contains a few FreeRTOS specifics required by
|
||||
mbedTLS.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user