[修改] 增加freeRTOS

1. 版本FreeRTOSv202212.01,命名为kernel;
This commit is contained in:
2023-05-06 16:43:01 +00:00
commit a345df017b
20944 changed files with 11094377 additions and 0 deletions

View 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/coreMQTT/issues), or [recently closed](https://github.com/FreeRTOS/coreMQTT/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/coreMQTT/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.

View File

@ -0,0 +1,15 @@
{
"lib_name": "coreMQTT",
"src": [
"source/core_mqtt.c",
"source/core_mqtt_state.c",
"source/core_mqtt_serializer.c"
],
"include": [
"source/include",
"source/interface"
],
"compiler_flags": [
"MQTT_DO_NOT_USE_CUSTOM_CONFIG"
]
}

View File

@ -0,0 +1,119 @@
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
cmake -S test -B build/ \
-G "Unix Makefiles" \
-DCMAKE_BUILD_TYPE=Debug \
-DBUILD_CLONE_SUBMODULES=ON \
-DCMAKE_C_FLAGS='--coverage -Wall -Wextra -Werror -DNDEBUG -DLIBRARY_LOG_LEVEL=LOG_DEBUG'
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
complexity:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Check complexity
uses: FreeRTOS/CI-CD-Github-Actions/complexity@main
with:
path: ./
horrid_threshold: 10
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-headers:
runs-on: ubuntu-latest
steps:
- name: Clone This Repo
uses: actions/checkout@v2
- name: Build
run: |
mkdir -p override-include
cp source/include/stdbool.readme override-include/stdbool.h
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 -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

View 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

View File

@ -0,0 +1,175 @@
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
delete_existing_tag_release:
description: 'Is this a re-release of existing tag/release? (Default: false)'
default: 'false'
required: false
jobs:
clean-existing-tag-and-release:
if: ${{ github.event.inputs.delete_existing_tag_release == 'true' }}
runs-on: ubuntu-latest
env:
VERSION_NUM: ${{ github.event.inputs.version_number }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Check if tag exists
run: |
git fetch origin
if git tag --list $VERSION_NUM
then
echo "Deleting existing tag for $VERSION_NUM"
git push origin --delete tags/$VERSION_NUM
fi
- name: Check if release exists
run: |
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-key 23F3D4EA75716059
sudo apt-add-repository https://cli.github.com/packages
sudo apt update
sudo apt-get install gh
if gh release list | grep $VERSION_NUM
then
echo "Deleting existing release for $VERSION_NUM"
gh release delete --yes $VERSION_NUM
fi
add-sbom-and-tag-commit:
if: ${{ ( github.event.inputs.delete_existing_tag_release == 'true' && success() ) || ( github.event.inputs.delete_existing_tag_release == 'false' && always() ) }}
needs: clean-existing-tag-and-release
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 "coreMQTT 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:
if: ${{ ( github.event.inputs.delete_existing_tag_release == 'true' && success() ) || ( github.event.inputs.delete_existing_tag_release == 'false' && always() ) }}
needs: add-sbom-and-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: coreMQTT
submodules: recursive
- name: Checkout disabled submodules
run: |
cd coreMQTT
git submodule update --init --checkout --recursive
- name: Create ZIP
run: |
zip -r coreMQTT-${{ github.event.inputs.version_number }}.zip coreMQTT -x "*.git*"
ls ./
- name: Validate created ZIP
run: |
mkdir zip-check
mv coreMQTT-${{ github.event.inputs.version_number }}.zip zip-check
cd zip-check
unzip coreMQTT-${{ github.event.inputs.version_number }}.zip -d coreMQTT-${{ github.event.inputs.version_number }}
ls coreMQTT-${{ github.event.inputs.version_number }}
diff -r -x "*.git*" coreMQTT-${{ github.event.inputs.version_number }}/coreMQTT/ ../coreMQTT/
cd ../
- name: Build
run: |
cd zip-check/coreMQTT-${{ github.event.inputs.version_number }}/coreMQTT
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 -DNDEBUG'
make -C build/ all
- name: Test
run: |
cd zip-check/coreMQTT-${{ github.event.inputs.version_number }}/coreMQTT/build/
ctest -E system --output-on-failure
cd ..
- name: Create artifact of ZIP
uses: actions/upload-artifact@v2
with:
name: coreMQTT-${{ github.event.inputs.version_number }}.zip
path: zip-check/coreMQTT-${{ github.event.inputs.version_number }}.zip
deploy-doxygen:
needs: add-sbom-and-tag-commit
if: ${{ ( github.event.inputs.delete_existing_tag_release == 'true' && success() ) || ( github.event.inputs.delete_existing_tag_release == 'false' && always() ) }}
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
if: ${{ ( github.event.inputs.delete_existing_tag_release == 'true' && success() ) || ( github.event.inputs.delete_existing_tag_release == 'false' && always() ) }}
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 coreMQTT Library.
draft: false
prerelease: false
- name: Download ZIP artifact
uses: actions/download-artifact@v2
with:
name: coreMQTT-${{ 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: ./coreMQTT-${{ github.event.inputs.version_number }}.zip
asset_name: coreMQTT-${{ github.event.inputs.version_number }}.zip
asset_content_type: application/zip

View File

@ -0,0 +1,16 @@
# Ignore documentation output.
**/docs/**/output/*
# Ignore CMake build directory.
build/
# Ignore build artifacts
*.o
# Ignore code coverage artifacts
*.gcda
*.gcno
*.gcov
# Ignore IDE setting folders
.vscode/

View File

@ -0,0 +1,4 @@
[submodule "test/unit-test/CMock"]
path = test/unit-test/CMock
url = https://github.com/ThrowTheSwitch/CMock
update = none

View File

@ -0,0 +1,80 @@
# Changelog for coreMQTT Client Library
## v2.1.1 (November 2022)
### Changes
- [#230](https://github.com/FreeRTOS/coreMQTT/pull/230) Fixed broken link in MISRA.md.
- [#229](https://github.com/FreeRTOS/coreMQTT/pull/229) Fixed multiple Subscribe Unsubscribe request sending logic.
## v2.1.0 (October 2022)
### Changes
- [#224](https://github.com/FreeRTOS/coreMQTT/pull/224) Update timeout duration to be constant for all transmit functions. Timeout shall occur if the whole packet is not sent within the configured timeout value.
- [#225](https://github.com/FreeRTOS/coreMQTT/pull/225) Updated the documentation of ReceiveLoop and ProcessLoop.
- [#223](https://github.com/FreeRTOS/coreMQTT/pull/223) Modify a check to make sure that keep alive is sent even when data is in the buffer.
## v2.0.0 (September 2022)
### Changes
- [#221](https://github.com/FreeRTOS/coreMQTT/pull/221) Remove LWT payload non-zero restriction.
- [#219](https://github.com/FreeRTOS/coreMQTT/pull/219) Fix MISRA deviations in the source.
- [#218](https://github.com/FreeRTOS/coreMQTT/pull/218) Fix bugs in receiveSingleIteration and optimize sendMessageVector.
- [#213](https://github.com/FreeRTOS/coreMQTT/pull/213) Fix MISRA deviations in the source.
- [#200](https://github.com/FreeRTOS/coreMQTT/pull/200) Add hooks to the code.
- [#205](https://github.com/FreeRTOS/coreMQTT/pull/205) Update logging and add MQTT_InitStatefulQoS to prevent log leaks.
- [#199](https://github.com/FreeRTOS/coreMQTT/pull/199) Make use of user provided buffer only for packet reception. Stack space will be used for sending packets.
- [#198](https://github.com/FreeRTOS/coreMQTT/pull/198) Remove timeout from MQTT\_ProcessLoop and MQTT\_ReceiveLoop and make the implementations non-blocking.
- [#196](https://github.com/FreeRTOS/coreMQTT/pull/196) Add a cancel callback API to cancel sent publish packets.
- [#191](https://github.com/FreeRTOS/coreMQTT/pull/191) Generate PINGREQ packets on idle input or output.
## v1.2.0 (November 2021)
### Changes
- [#175](https://github.com/FreeRTOS/coreMQTT/pull/175) Change levels of some logs.
- [#174](https://github.com/FreeRTOS/coreMQTT/pull/174) Fix warnings for some compiler options.
- [#148](https://github.com/FreeRTOS/coreMQTT/pull/148) Update doxygen version used for documentation to 1.9.2.
## v1.1.2 (July 2021)
### Updates
- [#168](https://github.com/FreeRTOS/coreMQTT/pull/168) Add header guards for C++ linkage.
- [#163](https://github.com/FreeRTOS/coreMQTT/pull/163) Fix bug to check for ping responses within `MQTT_PINGRESP_TIMEOUT_MS` instead of the entire keep alive interval.
- [#159](https://github.com/FreeRTOS/coreMQTT/pull/159) Add more checks for malformed packets when deserializing acknowledgments.
## v1.1.1 (February 2021)
### Changes
- [#142](https://github.com/FreeRTOS/coreMQTT/pull/142), [#143](https://github.com/FreeRTOS/coreMQTT/pull/143), and [#150](https://github.com/FreeRTOS/coreMQTT/pull/150) Documentation fixes.
## v1.1.0 (December 2020)
### Updates
- [#118](https://github.com/FreeRTOS/coreMQTT/pull/118) Use the `stdbool.h` header file instead of using preprocessor checks for when `bool` is not defined. This also provides `stdbool.readme` and `stdint.readme` files in the case that a non-C99 compiler does not provide the respective header.
- [#120](https://github.com/FreeRTOS/coreMQTT/pull/120) Introduce a `MQTT_RECV_POLLING_TIMEOUT_MS` configuration macro to control the timeout for retrying zero byte network read operations. Previously, network read attempts were controlled by a runtime timeout parameter, which could result in a premature timeout even when data could still be read. Now, reads will wait for at least the macro timeout value before returning error. Conversely, the macro timeout value is now the maximum duration during which no data may be received, regardless of the timeout passed at runtime.
- [#124](https://github.com/FreeRTOS/coreMQTT/pull/124), [#127](https://github.com/FreeRTOS/coreMQTT/pull/127), Introduce a `MQTT_SEND_RETRY_TIMEOUT_MS` configuration macro to control the similar case of retrying zero byte transport send operations.
- [#139](https://github.com/FreeRTOS/coreMQTT/pull/139) Add a parameter check for empty topic filters in SUBSCRIBE and UNSUBSCRIBE packets.
### Other
- [#107](https://github.com/FreeRTOS/coreMQTT/pull/107), [#109](https://github.com/FreeRTOS/coreMQTT/pull/109), [#121](https://github.com/FreeRTOS/coreMQTT/pull/121) Improve continuous integration checks.
- [#110](https://github.com/FreeRTOS/coreMQTT/pull/107) Rename the master branch to main.
- [#113](https://github.com/FreeRTOS/coreMQTT/pull/113), [#116](https://github.com/FreeRTOS/coreMQTT/pull/116), [#117](https://github.com/FreeRTOS/coreMQTT/pull/117), [#125](https://github.com/FreeRTOS/coreMQTT/pull/125) Update logging and cast to C standard types for logs.
- [#115](https://github.com/FreeRTOS/coreMQTT/pull/115), [#122](https://github.com/FreeRTOS/coreMQTT/pull/122), [#128](https://github.com/FreeRTOS/coreMQTT/pull/128), [#132](https://github.com/FreeRTOS/coreMQTT/pull/132), [#133](https://github.com/FreeRTOS/coreMQTT/pull/133), [#136](https://github.com/FreeRTOS/coreMQTT/pull/136), [#138](https://github.com/FreeRTOS/coreMQTT/pull/138) Minor documentation updates.
## v1.0.1 (November 2020)
### Updates
- [#83](https://github.com/FreeRTOS/coreMQTT/pull/83) Accept duplicate publishes regardless of the value of the "DUP" flag.
- [#86](https://github.com/FreeRTOS/coreMQTT/pull/86) Remove `const` qualifier from transport interface function pointers.
- [#91](https://github.com/FreeRTOS/coreMQTT/pull/91) `transport_interface.h` was moved to the `interface/` directory.
### Other
- [#69](https://github.com/FreeRTOS/coreMQTT/pull/69), [#80](https://github.com/FreeRTOS/coreMQTT/pull/80), [#95](https://github.com/FreeRTOS/coreMQTT/pull/95), [#98](https://github.com/FreeRTOS/coreMQTT/pull/98) Minor documentation updates.
- [#71](https://github.com/FreeRTOS/coreMQTT/pull/71) Set publish payloads to NULL when they are zero length.
- [#74](https://github.com/FreeRTOS/coreMQTT/pull/74) Resolve clang build warnings from the unit tests.
- [#75](https://github.com/FreeRTOS/coreMQTT/pull/75) Configure submodules to not be cloned by default.
## v1.0.0 (September 2020)
This is the first release of a coreMQTT client library in this repository.
The MQTT library is a client-side implementation that is compliant with the [MQTT 3.1.1 specification](https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html). It is optimized for resource-constrained devices, and does not allocate any memory.

View File

@ -0,0 +1,53 @@
FROM ubuntu:22.04
ENV UID=1000
ENV GID=1000
ENV USER=ubuntu
WORKDIR /tmp
COPY requirements.txt .
SHELL ["/bin/bash", "-c"]
RUN apt-get clean \
&& apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
build-essential \
clang-format cmake gcc-11 g++-11 gdb \
git \
lcov \
libfmt-dev \
libpython3-dev \
libspdlog-dev \
locales \
ninja-build \
packaging-dev \
python3-pip \
python3-venv \
ruby \
software-properties-common \
tmux \
uncrustify \
&& pip3 install -r requirements.txt \
&& wget --progress=dot:giga https://github.com/danmar/cppcheck/archive/2.6.tar.gz \
&& tar xvzf 2.6.tar.gz \
&& mkdir cppcheck-2.6/build \
&& cd cppcheck-2.6/build \
&& cmake .. -GNinja \
&& ninja \
&& ninja install \
&& groupadd $USER -g $GID \
&& adduser $USER --gid $UID --uid 1000 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
&& locale-gen en_US.UTF-8 \
&& echo "${USER} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
USER $USER
RUN wget -qO - https://sh.rustup.rs | sh -s -- --no-modify-path -y
ENV PATH="/home/${USER}/.cargo/bin:${PATH}"
RUN rustup component add rustfmt clippy

View File

@ -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.

View File

@ -0,0 +1,39 @@
# MISRA Compliance
The coreMQTT library files conform to the [MISRA C:2012](https://www.misra.org.uk/misra-c)
guidelines, with the deviations listed below. Compliance is checked with Coverity static analysis.
Since the coreMQTT library is designed for small-embedded devices, it needs to have a very small memory footprint and has to
be efficient. To achieve that and to increase the performace of the library, it deviates from some MISRA rules.
The specific deviations, suppressed inline, are listed below.
Additionally, [MISRA configuration file](https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/test/Coverity/coverity_misra.config) contains the project wide deviations.
### Suppressed with Coverity Comments
To find the deviation references in the source files run grep on the source code
with ( Assuming rule 18.2 violation; with justification in point 1 ):
```
grep 'MISRA Ref 18.2.1' . -rI
```
#### Rule 10.8
_Ref 10.8.1_
- MISRA C-2012 Rule 10.8 states that value of composite expressions should not be cast
to variables of different signedness. In this library, array of bytes are used to
process data. Functions which fill the arrays with data update an index to an
offset. To know the amount of data added to the array, the beginning address of the
array has to be subtracted from the index. When the two pointers are subracted, it
results in a signed value. It is verified however that the value will always be positive.
And thus, can be casted and added to a size_t variable (which is unsigned).
#### Rule 18.2
_Ref 18.2.1_
- MISRA C-2012 Rule 18.2 states that two pointers may only be subtracted if they point
to elements of the same array. In this library, array of bytes are used to process
data. Functions which fill the arrays with data update an index to an offset.
To know the amount of data added to the array, the beginning address of the array has
to be subtracted from the index. It is manually verified that the index will always be
within bounds of the array. However, Coverity is flagging this as a deviation. Thus, we
are suppressing it.

View File

@ -0,0 +1,234 @@
## coreMQTT version >=v2.0.0 Migration Guide
With coreMQTT versions >=v2.0.0, there are some breaking changes that need to be addressed when upgrading.
### Breaking Changes
* The `MQTT_ProcessLoop` function no longer uses a timeout as this led to unavoidable busy-waiting. Thus, the signature of `MQTT_ProcessLoop` changed from `MQTTStatus_t MQTT_ProcessLoop( MQTTContext_t * pContext, uint32_t timeoutMs )` to `MQTTStatus_t MQTT_ProcessLoop( MQTTContext_t * pContext )`. Additionally, `MQTT_ProcessLoop` can now return `MQTTNeedMoreBytes`. A return of `MQTTNeedMoreBytes` means that `MQTT_ProcessLoop` received only a part of an MQTT packet and will need to be called again (probably after a bit of delay) in order to finish receiving the MQTT packet. Thus, to migrate, simply remove the timeout from the `MQTT_ProcessLoop` call and additionally check for if `MQTTNeedMoreBytes` has been returned when checking the status of `MQTT_ProcessLoop`. For example:
**Old Code Snippet**:
```
// Variables used in this example.
MQTTStatus_t status;
uint32_t timeoutMs = 100;
// This context is assumed to be initialized and connected.
MQTTContext_t * pContext;
while( true )
{
status = MQTT_ProcessLoop( pContext, timeoutMs );
if( status != MQTTSuccess )
{
// Determine the error. It's possible we might need to disconnect
// the underlying transport connection.
}
else
{
// Other application functions.
}
}
```
**New Code Snippet**:
```
// Variables used in this example.
MQTTStatus_t status;
// This context is assumed to be initialized and connected.
MQTTContext_t * pContext;
while( true )
{
status = MQTT_ProcessLoop( pContext );
if( status != MQTTSuccess && status != MQTTNeedMoreBytes )
{
// Determine the error. It's possible we might need to disconnect
// the underlying transport connection.
}
/* else if only required if the terminating else is empty and the application doesn't want a scenario akin to busy waiting. */
else if( status == MQTTNeedMoreBytes )
{
/* Only a partial MQTT packet is received. Call MQTT_ProcessLoop again; ideally after a small delay. */
}
else
{
// Other application functions.
}
}
```
* The `MQTT_ReceiveLoop` function no longer uses a timeout as this led to unavoidable busy-waiting. Thus, the signature of `MQTT_ReceiveLoop` changed from `MQTTStatus_t MQTT_ReceiveLoop( MQTTContext_t * pContext, uint32_t timeoutMs )` to `MQTTStatus_t MQTT_ReceiveLoop( MQTTContext_t * pContext )`. Additionally, `MQTT_ReceiveLoop` can now return `MQTTNeedMoreBytes`. A return of `MQTTNeedMoreBytes` means that `MQTT_ReceiveLoop` received only a part of an MQTT packet and will need to be called again (probably after a bit of delay) in order to finish receiving the MQTT packet. Thus, to migrate, simply remove the timeout from the `MQTT_ReceiveLoop` call and additionally check for if `MQTTNeedMoreBytes` has been returned when checking the status of `MQTT_ReceiveLoop`. For example:
**Old Code Snippet**:
```
// Variables used in this example.
MQTTStatus_t status;
uint32_t timeoutMs = 100;
// This context is assumed to be initialized and connected.
MQTTContext_t * pContext;
while( true )
{
status = MQTT_ReceiveLoop( pContext, timeoutMs );
if( status != MQTTSuccess )
{
// Determine the error. It's possible we might need to disconnect
// the underlying transport connection.
}
else
{
// Other application functions.
}
}
```
**New Code Snippet**:
```
// Variables used in this example.
MQTTStatus_t status;
// This context is assumed to be initialized and connected.
MQTTContext_t * pContext;
while( true )
{
status = MQTT_ReceiveLoop( pContext );
if( status != MQTTSuccess && status != MQTTNeedMoreBytes )
{
// Determine the error. It's possible we might need to disconnect
// the underlying transport connection.
}
/* else if only required if the terminating else is empty and the application doesn't want a scenario akin to busy waiting. */
else if( status == MQTTNeedMoreBytes )
{
/* Only a partial MQTT packet is received. Call MQTT_ReceiveLoop again; ideally after a small delay. */
}
else
{
// Other application functions.
}
}
```
* The `TransportInterface_t` structure now has a new member `writev`. It uses scatter-gather approach to send multiple MQTT packet components as a single packet to reduce overhead and improve performance. However, it is COMPLETELY OPTIONAL to implement. To that end, when application(s) initialize a `TransportInterface_t` structure, they **MUST** either set `writev` to a working implementation or set it `NULL`. Not doing this will lead to undefined behavior as the coreMQTT library checks if `writev` is `NULL` to determine if it should be used. For example:
**Old Code Snippet**:
```
TransportInterface_t transport;
// Set transport interface members.
transport.pNetworkInterface = &someNetworkInterface;
transport.send = networkSend;
transport.recv = networkRecv;
```
**New Code Snippet**:
```
TransportInterface_t transport;
// Set transport interface members.
transport.pNetworkInterface = &someNetworkInterface;
transport.send = networkSend;
transport.recv = networkRecv;
transport.writev = NULL;
```
* The `MQTT_Init` function no longer creates buffers to handle QoS > 0 packets, so if planning to use QoS > 0, the `MQTT_InitStatefulQoS` function must also be called on an `MQTTContext_t` after calling `MQTT_Init` on it and before using any other coreMQTT functions with it. If not using QoS > 0, `MQTT_InitStatefulQoS` does not need to be called. For example (code that uses QoS > 0):
**Old Code Snippet**:
```
// Function for obtaining a timestamp.
uint32_t getTimeStampMs();
// Callback function for receiving packets.
void eventCallback(
MQTTContext_t * pContext,
MQTTPacketInfo_t * pPacketInfo,
MQTTDeserializedInfo_t * pDeserializedInfo
);
// Network send.
int32_t networkSend( NetworkContext_t * pContext, const void * pBuffer, size_t bytes );
// Network receive.
int32_t networkRecv( NetworkContext_t * pContext, void * pBuffer, size_t bytes );
MQTTContext_t mqttContext;
TransportInterface_t transport;
MQTTFixedBuffer_t fixedBuffer;
uint8_t buffer[ 1024 ];
// Clear context.
memset( ( void * ) &mqttContext, 0x00, sizeof( MQTTContext_t ) );
// Set transport interface members.
transport.pNetworkInterface = &someNetworkInterface;
transport.send = networkSend;
transport.recv = networkRecv;
// Set buffer members.
fixedBuffer.pBuffer = buffer;
fixedBuffer.size = 1024;
status = MQTT_Init( &mqttContext, &transport, getTimeStampMs, eventCallback, &fixedBuffer );
if( status == MQTTSuccess )
{
// Do something with mqttContext. The transport and fixedBuffer structs were
// copied into the context, so the original structs do not need to stay in scope.
}
```
**New Code Snippet**:
```
// Function for obtaining a timestamp.
uint32_t getTimeStampMs();
// Callback function for receiving packets.
void eventCallback(
MQTTContext_t * pContext,
MQTTPacketInfo_t * pPacketInfo,
MQTTDeserializedInfo_t * pDeserializedInfo
);
// Network send.
int32_t networkSend( NetworkContext_t * pContext, const void * pBuffer, size_t bytes );
// Network receive.
int32_t networkRecv( NetworkContext_t * pContext, void * pBuffer, size_t bytes );
MQTTContext_t mqttContext;
TransportInterface_t transport;
MQTTFixedBuffer_t fixedBuffer;
uint8_t buffer[ 1024 ];
static MQTTPubAckInfo_t pOutgoingPublishRecords[ OUTGOING_PUBLISH_RECORD_COUNT ];
static MQTTPubAckInfo_t pIncomingPublishRecords[ INCOMING_PUBLISH_RECORD_COUNT ];
// Clear context.
memset( ( void * ) &mqttContext, 0x00, sizeof( MQTTContext_t ) );
// Set transport interface members.
transport.pNetworkInterface = &someNetworkInterface;
transport.send = networkSend;
transport.recv = networkRecv;
transport.writev = NULL;
// Set buffer members.
fixedBuffer.pBuffer = buffer;
fixedBuffer.size = 1024;
status = MQTT_Init( &mqttContext, &transport, getTimeStampMs, eventCallback, &fixedBuffer );
if( status == MQTTSuccess )
{
// Initialize MQTT context for QoS > 0. This only has to be done if
// performing QoS > 0 operations.
status = MQTT_InitStatefulQoS(pxMQTTContext,
pOutgoingPublishRecords,
OUTGOING_PUBLISH_RECORD_COUNT,
pIncomingPublishRecords,
INCOMING_PUBLISH_RECORD_COUNT);
}
if( status == MQTTSuccess )
{
// Do something with mqttContext. The transport and fixedBuffer structs were
// copied into the context, so the original structs do not need to stay in scope.
}
```
* For coreMQTT version >=v2.1.0, the `MQTT_SEND_RETRY_TIMEOUT_MS` macro configuration has been deprecated. It has been replaced with `MQTT_SEND_TIMEOUT_MS`. `MQTT_SEND_RETRY_TIMEOUT_MS` was formerly used to timeout sending an MQTT packet after the transport `send` function failed to transmit any bytes for too long. This timeout would reset each time the transport `send` function sent any bytes, leading to the actual timeout scaling with the number of bytes being sent. In other words, the maximum time for sending a packet was variable. In order to remedy this, the `MQTT_SEND_RETRY_TIMEOUT_MS` macro was replaced with `MQTT_SEND_TIMEOUT_MS`. `MQTT_SEND_TIMEOUT_MS` now sets the maximum duration that coreMQTT will attempt to send an MQTT packet, leading to more consistent timeout behavior across various APIs and packet lengths.
### Additional Changes
* The `MQTT_CancelCallback` function has been added to allow a program to prevent the event callback from being called when receiving an ACK for a sent packet. For example, if a program sends a publish with packet ID 2 and QoS > 0 using `MQTT_Publish`, the program could then call `MQTT_CancelCallback` on packet ID 2 to prevent coreMQTT from calling the event callback when it receives the `PUBACK` for packet ID 2.

View File

@ -0,0 +1,165 @@
# coreMQTT Client Library
This repository contains the coreMQTT library that has been optimized for a low memory footprint. The coreMQTT library is compliant with the [MQTT 3.1.1](https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html) standard. It has no dependencies on any additional libraries other than the standard C library, a customer-implemented network transport interface, and *optionally* a user-implemented platform time function. This library is distributed under the [MIT Open Source License](LICENSE).
This library has gone through code quality checks including verification that no function has a [GNU Complexity](https://www.gnu.org/software/complexity/manual/complexity.html) score over 8, and checks against deviations from mandatory rules in the [MISRA coding standard](https://www.misra.org.uk). Deviations from the MISRA C:2012 guidelines are documented under [MISRA Deviations](MISRA.md). This library has also undergone both static code analysis from [Coverity static analysis](https://scan.coverity.com/), and validation of memory safety through the [CBMC automated reasoning tool](https://www.cprover.org/cbmc/).
See memory requirements for this library [here](./docs/doxygen/include/size_table.md).
**coreMQTT v2.1.1 [source code](https://github.com/FreeRTOS/coreMQTT/tree/v2.1.1/source) is part of the [FreeRTOS 202210.01 LTS](https://github.com/FreeRTOS/FreeRTOS-LTS/tree/202210.01-LTS) release.**
## MQTT Config File
The MQTT client library exposes build configuration macros that are required for building the library.
A list of all the configurations and their default values are defined in [core_mqtt_config_defaults.h](source/include/core_mqtt_config_defaults.h).
To provide custom values for the configuration macros, a custom config file named `core_mqtt_config.h` can be
provided by the application to the library.
By default, a `core_mqtt_config.h` custom config is required to build the library. To disable this requirement
and build the library with default configuration values, provide `MQTT_DO_NOT_USE_CUSTOM_CONFIG` as a compile time preprocessor macro.
**Thus, the MQTT library can be built by either**:
* Defining a `core_mqtt_config.h` file in the application, and adding it to the include directories list of the library
**OR**
* Defining the `MQTT_DO_NOT_USE_CUSTOM_CONFIG` preprocessor macro for the library build.
## Sending metrics to AWS IoT
When establishing a connection with AWS IoT, users can optionally report the Operating System, Hardware Platform and MQTT client version information of their device to AWS. This information can help AWS IoT provide faster issue resolution and technical support. If users want to report this information, they can send a specially formatted string (see below) in the username field of the MQTT CONNECT packet.
Format
The format of the username string with metrics is:
```
<Actual_Username>?SDK=<OS_Name>&Version=<OS_Version>&Platform=<Hardware_Platform>&MQTTLib=<MQTT_Library_name>@<MQTT_Library_version>
```
Where
* <Actual_Username> is the actual username used for authentication, if username and password are used for authentication. When username and password based authentication is not used, this
is an empty value.
* <OS_Name> is the Operating System the application is running on (e.g. FreeRTOS)
* <OS_Version> is the version number of the Operating System (e.g. V10.4.3)
* <Hardware_Platform> is the Hardware Platform the application is running on (e.g. WinSim)
* <MQTT_Library_name> is the MQTT Client library being used (e.g. coreMQTT)
* <MQTT_Library_version> is the version of the MQTT Client library being used (e.g. 1.0.2)
Example
* Actual_Username = “iotuser”, OS_Name = FreeRTOS, OS_Version = V10.4.3, Hardware_Platform_Name = WinSim, MQTT_Library_Name = coremqtt, MQTT_Library_version = 2.1.1. If username is not used, then “iotuser” can be removed.
```
/* Username string:
* iotuser?SDK=FreeRTOS&Version=v10.4.3&Platform=WinSim&MQTTLib=coremqtt@2.1.1
*/
#define OS_NAME "FreeRTOS"
#define OS_VERSION "V10.4.3"
#define HARDWARE_PLATFORM_NAME "WinSim"
#define MQTT_LIB "coremqtt@2.1.1"
#define USERNAME_STRING "iotuser?SDK=" OS_NAME "&Version=" OS_VERSION "&Platform=" HARDWARE_PLATFORM_NAME "&MQTTLib=" MQTT_LIB
#define USERNAME_STRING_LENGTH ( ( uint16_t ) ( sizeof( USERNAME_STRING ) - 1 ) )
MQTTConnectInfo_t connectInfo;
connectInfo.pUserName = USERNAME_STRING;
connectInfo.userNameLength = USERNAME_STRING_LENGTH;
mqttStatus = MQTT_Connect( pMqttContext, &connectInfo, NULL, CONNACK_RECV_TIMEOUT_MS, pSessionPresent );
```
## Upgrading to v2.0.0 and above
With coreMQTT versions >=v2.0.0, there are breaking changes. Please refer to the [coreMQTT version >=v2.0.0 Migration Guide](MigrationGuide.md).
## Building the Library
The [mqttFilePaths.cmake](mqttFilePaths.cmake) file contains the information of all source files and the header include path required to build the MQTT library.
Additionally, the MQTT library requires two header files that are not part of the ISO C90 standard library, `stdbool.h` and `stdint.h`. For compilers that do not provide these header files, the [source/include](source/include) directory contains the files [stdbool.readme](source/include/stdbool.readme) and [stdint.readme](source/include/stdint.readme), which can be renamed to `stdbool.h` and `stdint.h`, respectively, to provide the type definitions required by MQTT.
As mentioned in the previous section, either a custom config file (i.e. `core_mqtt_config.h`) OR `MQTT_DO_NOT_USE_CUSTOM_CONFIG` macro needs to be provided to build the MQTT library.
For a CMake example of building the MQTT library with the `mqttFilePaths.cmake` file, refer to the `coverity_analysis` library target in [test/CMakeLists.txt](test/CMakeLists.txt) file.
## Building Unit Tests
### Checkout CMock 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 CMock is required. Use the following command to clone the submodule:
```
git submodule update --checkout --init --recursive test/unit-test/CMock
```
### Platform Prerequisites
- Docker
or the following:
- For running unit tests
- **C90 compiler** like gcc
- **CMake 3.13.0 or later**
- **Ruby 2.0.0 or later** is additionally required for the CMock test framework (that we use).
- For running the coverage target, **gcov** and **lcov** are additionally required.
### Steps to build **Unit Tests**
1. If using docker, launch the container:
1. `docker build -t coremqtt .`
1. `docker run -it -v "$PWD":/workspaces/coreMQTT -w /workspaces/coreMQTT coremqtt`
1. Go to the root directory of this repository. (Make sure that the **CMock** submodule is cloned as described [above](#checkout-cmock-submodule))
1. Run the *cmake* command: `cmake -S test -B build`
1. Run this command to build the library and unit tests: `make -C build all`
1. The generated test executables will be present in `build/bin/tests` folder.
1. Run `cd build && ctest` to execute all tests and view the test run summary.
## CBMC
To learn more about CBMC and proofs specifically, review the training material [here](https://model-checking.github.io/cbmc-training).
The `test/cbmc/proofs` directory contains CBMC proofs.
In order to run these proofs you will need to install CBMC and other tools by following the instructions [here](https://model-checking.github.io/cbmc-training/installation.html).
## Reference examples
Please refer to the demos of the MQTT client library in the following locations for reference examples on POSIX and FreeRTOS platforms:
| Platform | Location | Transport Interface Implementation |
| :-: | :-: | :-: |
| POSIX | [AWS IoT Device SDK for Embedded C](https://github.com/aws/aws-iot-device-sdk-embedded-C/tree/main/demos/mqtt) | POSIX sockets for TCP/IP and OpenSSL for TLS stack
| FreeRTOS | [FreeRTOS/FreeRTOS](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo) | FreeRTOS+TCP for TCP/IP and mbedTLS for TLS stack |
| FreeRTOS | [FreeRTOS AWS Reference Integrations](https://github.com/aws/amazon-freertos/tree/main/demos/coreMQTT) | Based on Secure Sockets Abstraction |
## Documentation
### Existing Documentation
For pre-generated documentation, please see the documentation linked in the locations below:
| Location |
| :-: |
| [AWS IoT Device SDK for Embedded C](https://github.com/aws/aws-iot-device-sdk-embedded-C#releases-and-documentation) |
| [FreeRTOS.org](https://freertos.org/Documentation/api-ref/coreMQTT/docs/doxygen/output/html/index.html) |
Note that the latest included version of coreMQTT may differ across repositories.
### Generating Documentation
The Doxygen references were created using Doxygen version 1.9.2. To generate the
Doxygen pages, please run the following command from the root of this repository:
```shell
doxygen docs/doxygen/config.doxyfile
```
## Contributing
See [CONTRIBUTING.md](./.github/CONTRIBUTING.md) for information on contributing.

View File

@ -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.

View File

@ -0,0 +1,30 @@
<table>
<tr>
<td colspan="3"><center><b>Code Size of coreMQTT (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>core_mqtt.c</td>
<td><center>4.1K</center></td>
<td><center>3.4K</center></td>
</tr>
<tr>
<td>core_mqtt_state.c</td>
<td><center>1.7K</center></td>
<td><center>1.3K</center></td>
</tr>
<tr>
<td>core_mqtt_serializer.c</td>
<td><center>2.8K</center></td>
<td><center>2.2K</center></td>
</tr>
<tr>
<td><b>Total estimates</b></td>
<td><b><center>8.6K</center></b></td>
<td><b><center>6.9K</center></b></td>
</tr>
</table>

View File

@ -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>

View File

@ -0,0 +1,358 @@
/**
@mainpage Overview
@anchor mqtt
@brief MQTT 3.1.1 client library
> MQTT stands for MQ Telemetry Transport. It is a publish/subscribe, extremely simple and lightweight messaging protocol, designed for constrained devices and low-bandwidth, high-latency or unreliable networks. The design principles are to minimise network bandwidth and device resource requirements whilst also attempting to ensure reliability and some degree of assurance of delivery. These principles also turn out to make the protocol ideal of the emerging "machine-to-machine" (M2M) or "Internet of Things" world of connected devices, and for mobile applications where bandwidth and battery power are at a premium.
<span style="float:right;margin-right:4em"> &mdash; <i>Official description of MQTT from [mqtt.org](https://mqtt.org)</i></span><br>
This MQTT library implements the client side of the MQTT 3.1.1 protocol. This library is optimized for resource constrained embedded devices. Features of this library include:
- Fully synchronous API, to allow applications to completely manage their concurrency and multi-threading method.
- Operations on fixed buffers, so that applications may control their memory allocation strategy.
- Scalable performance and footprint. The [configuration settings](@ref core_mqtt_config) allow this library to be tailored to a system's resources.
Please see https://github.com/aws/aws-iot-device-sdk-embedded-C/tree/main/demos/mqtt for example code demonstrating integration with TLS.
@section mqtt_memory_requirements Memory Requirements
@brief Memory requirements of the MQTT library.
@include{doc} size_table.md
*/
/**
@page mqtt_design Design
@brief Architecture of the MQTT library.
This MQTT client library provides an implementation of the [MQTT 3.1.1 specification](https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html). It is optimized for resource constrained devices and does not allocate any memory.
@section mqtt_interfaces Interfaces and Callbacks
The MQTT library relies on interfaces to dissociate itself from platform specific functionality,
such as the transport layer or maintaining time. Interfaces used by MQTT are simply function pointers
with expectations of behavior.
The MQTT library expects the application to provide implementations for the following interfaces:
<table>
<tr>
<td><b>Function Pointer</b></td>
<td><b>Use</b></td>
</tr>
<tr>
<td>@ref TransportRecv_t</td>
<td>Receiving data from an established network connection.</td>
</tr>
<tr>
<td>@ref TransportSend_t</td>
<td>Sending data over an established network connection.</td>
</tr>
<tr>
<td>@ref MQTTGetCurrentTimeFunc_t</td>
<td>Obtaining timestamps for complying with user-specified timeouts and the MQTT keep-alive mechanism.</td>
</tr>
<tr>
<td>@ref MQTTEventCallback_t</td>
<td>Returning packets received from the network to the user application after deserialization.</td>
</tr>
</table>
@section mqtt_serializers Serializers and Deserializers
The managed MQTT API in @ref core_mqtt.h uses a set of serialization and deserialization functions
declared in @ref core_mqtt_serializer.h. If a user does not want to use the functionality provided by the managed API,
these low-level functions can be used directly:
- @ref mqtt_getconnectpacketsize_function <br>
- @ref mqtt_serializeconnect_function <br>
- @ref mqtt_getsubscribepacketsize_function <br>
- @ref mqtt_serializesubscribe_function <br>
- @ref mqtt_getunsubscribepacketsize_function <br>
- @ref mqtt_serializeunsubscribe_function <br>
- @ref mqtt_getpublishpacketsize_function <br>
- @ref mqtt_serializepublish_function <br>
- @ref mqtt_serializepublishheader_function <br>
- @ref mqtt_serializeack_function <br>
- @ref mqtt_getdisconnectpacketsize_function <br>
- @ref mqtt_serializedisconnect_function <br>
- @ref mqtt_getpingreqpacketsize_function <br>
- @ref mqtt_serializepingreq_function <br>
- @ref mqtt_deserializepublish_function <br>
- @ref mqtt_deserializeack_function <br>
- @ref mqtt_getincomingpackettypeandlength_function <br>
@section mqtt_sessions Sessions and State
The MQTT 3.1.1 protocol allows for a client and server to maintain persistent sessions, which
can be resumed after a reconnect. The elements of a session stored by this client library consist
of the states of incomplete publishes with Quality of Service levels of 1 (at least once), or 2 (exactly once).
These states are stored in the pointers pointed to by @ref MQTTContext_t.outgoingPublishRecords and @ref MQTTContext_t.incomingPublishRecords;
This library does not store any subscription information, nor any information for QoS 0 publishes.
When resuming a persistent session, the client library will resend PUBRELs for all PUBRECs that had been received
for incomplete outgoing QoS 2 publishes. If the broker does not resume the session, then all state information
in the client will be reset.
@note The library stores only the <i>state</i> of incomplete publishes and not the publish payloads. It is the responsibility of the user application to save publish payloads until the publish is complete.
If a persistent session is resumed, then @ref mqtt_publishtoresend_function should be called to obtain the
packet identifiers of incomplete publishes, followed by a call to @ref mqtt_publish_function to resend the
unacknowledged publish.
@section mqtt_receivepackets Packet Reception
MQTT Packets are received from the network with calls to @ref mqtt_processloop_function or @ref mqtt_receiveloop_function. These functions are mostly identical,
with the exception of keep-alive; the former sends ping requests and processes ping responses to ensure the MQTT session does not remain idle for more than the keep-alive interval, while the latter does not.
Since calls to @ref mqtt_publish_function, @ref mqtt_subscribe_function, and @ref mqtt_unsubscribe_function only send packets and do not
wait for acknowledgments, a call to @ref mqtt_processloop_function or @ref mqtt_receiveloop_function must follow in order to receive any expected acknowledgment.
The exception is @ref mqtt_connect_function; since a MQTT session cannot be considered established until the server acknowledges a CONNECT packet with a CONNACK,
the function waits until the CONNACK is received.
@subsection mqtt_receivetimeout Runtime Timeouts passed to MQTT library
@ref mqtt_connect_function, @ref mqtt_processloop_function, and @ref mqtt_receiveloop_function all accept a timeout parameter for packet reception.<br>
For the @ref mqtt_connect_function, if this value is set to 0, then instead of a time-based loop, it will attempt to call the transport receive function up to a maximum number of retries,
which is defined by @ref MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT.
For @ref mqtt_processloop_function and @ref mqtt_receiveloop_function, the timeout value represents the <i>minimum</i> duration that will be spent in the function, provided there are no network errors.
Should the timeout be set to 0, then the loop will run for a single iteration. A single iteration of a loop consists of an attempt to receive a single byte from the network, and
if the single byte receive was successful, then attempt(s) to receive the rest of the packet (with retry attempts governed by @ref MQTT_RECV_POLLING_TIMEOUT_MS), followed by sending acknowledgement response, if needed
(with retry attempts governed by @ref MQTT_SEND_TIMEOUT_MS), and then, finally deserialization of the packet received and a call to the application callback.
If the first read did not succeed, then instead the library checks if a ping request needs to be sent (only for the process loop).
See the below diagrams for a representation of the above flows:
| MQTT Connect Diagram | MQTT ProcessLoop Diagram | MQTT ReceiveLoop Diagram |
| :--: | :--: | :--: |
|<img src="mqtt_connect_design.png" alt="MQTT Connect" width=100% /> |<img src="mqtt_processloop_design.png" alt="MQTT Process Loop" width=100% /> |<img src="mqtt_receiveloop_design.png" alt="MQTT Receive Loop" width=100% /> |
@section mqtt_keepalive Keep-Alive
The MQTT standard specifies a keep-alive mechanism to detect half-open or otherwise unusable network connections.
An MQTT client will send periodic ping requests (PINGREQ) to the server if the connection is idle. The MQTT server must respond to ping requests with a ping response (PINGRESP).
In this library, @ref mqtt_processloop_function handles sending of PINGREQs and processing corresponding PINGRESPs to comply with the keep-alive interval set in @ref MQTTContext_t.keepAliveIntervalSec.
The standard does not specify the time duration within which the server has to respond to a ping request, noting only a "reasonable amount of time". If the response to a ping request is not received within @ref MQTT_PINGRESP_TIMEOUT_MS, this library assumes that the connection is dead.
If @ref mqtt_receiveloop_function is used instead of @ref mqtt_processloop_function, then no ping requests are sent. The application must ensure the connection does not remain idle for more than the keep-alive interval by calling @ref mqtt_ping_function to send ping requests.
The timestamp in @ref MQTTContext_t.lastPacketTxTime indicates when a packet was last sent by the library.
Sending any ping request sets the @ref MQTTContext_t.waitingForPingResp flag. This flag is cleared by @ref mqtt_processloop_function when a ping response is received. If @ref mqtt_receiveloop_function is used instead, then this flag must be cleared manually by the application's callback.
*/
/**
@page core_mqtt_config Configurations
@brief Configurations of the MQTT Library.
<!-- @par configpagestyle allows the @section titles to be styled according to style.css -->
@par configpagestyle
Some configuration settings are C pre-processor constants, and some are function-like macros for logging. They can be set with a `#define` in the config file (**core_mqtt_config.h**) or by using a compiler option such as -D in gcc.
@section MQTT_DO_NOT_USE_CUSTOM_CONFIG
@copydoc MQTT_DO_NOT_USE_CUSTOM_CONFIG
@section MQTT_PINGRESP_TIMEOUT_MS
@copydoc MQTT_PINGRESP_TIMEOUT_MS
@section MQTT_RECV_POLLING_TIMEOUT_MS
@copydoc MQTT_RECV_POLLING_TIMEOUT_MS
@section MQTT_SEND_TIMEOUT_MS
@copydoc MQTT_SEND_TIMEOUT_MS
@section MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT
@copydoc MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT
@section mqtt_logerror LogError
@copydoc LogError
@section mqtt_logwarn LogWarn
@copydoc LogWarn
@section mqtt_loginfo LogInfo
@copydoc LogInfo
@section mqtt_logdebug LogDebug
@copydoc LogDebug
*/
/**
@page mqtt_functions Functions
@brief Primary functions of the MQTT library:<br><br>
@subpage mqtt_init_function <br>
@subpage mqtt_connect_function <br>
@subpage mqtt_subscribe_function <br>
@subpage mqtt_publish_function <br>
@subpage mqtt_ping_function <br>
@subpage mqtt_unsubscribe_function <br>
@subpage mqtt_disconnect_function <br>
@subpage mqtt_processloop_function <br>
@subpage mqtt_receiveloop_function <br>
@subpage mqtt_getpacketid_function <br>
@subpage mqtt_getsubackstatuscodes_function <br>
@subpage mqtt_status_strerror_function <br>
@subpage mqtt_publishtoresend_function <br><br>
Serializer functions of the MQTT library:<br><br>
@subpage mqtt_getconnectpacketsize_function <br>
@subpage mqtt_serializeconnect_function <br>
@subpage mqtt_getsubscribepacketsize_function <br>
@subpage mqtt_serializesubscribe_function <br>
@subpage mqtt_getunsubscribepacketsize_function <br>
@subpage mqtt_serializeunsubscribe_function <br>
@subpage mqtt_getpublishpacketsize_function <br>
@subpage mqtt_serializepublish_function <br>
@subpage mqtt_serializepublishheader_function <br>
@subpage mqtt_serializeack_function <br>
@subpage mqtt_getdisconnectpacketsize_function <br>
@subpage mqtt_serializedisconnect_function <br>
@subpage mqtt_getpingreqpacketsize_function <br>
@subpage mqtt_serializepingreq_function <br>
@subpage mqtt_deserializepublish_function <br>
@subpage mqtt_deserializeack_function <br>
@subpage mqtt_getincomingpackettypeandlength_function <br>
@page mqtt_init_function MQTT_Init
@snippet core_mqtt.h declare_mqtt_init
@copydoc MQTT_Init
@page mqtt_connect_function MQTT_Connect
@snippet core_mqtt.h declare_mqtt_connect
@copydoc MQTT_Connect
@page mqtt_subscribe_function MQTT_Subscribe
@snippet core_mqtt.h declare_mqtt_subscribe
@copydoc MQTT_Subscribe
@page mqtt_publish_function MQTT_Publish
@snippet core_mqtt.h declare_mqtt_publish
@copydoc MQTT_Publish
@page mqtt_ping_function MQTT_Ping
@snippet core_mqtt.h declare_mqtt_ping
@copydoc MQTT_Ping
@page mqtt_unsubscribe_function MQTT_Unsubscribe
@snippet core_mqtt.h declare_mqtt_unsubscribe
@copydoc MQTT_Unsubscribe
@page mqtt_disconnect_function MQTT_Disconnect
@snippet core_mqtt.h declare_mqtt_disconnect
@copydoc MQTT_Disconnect
@page mqtt_processloop_function MQTT_ProcessLoop
@snippet core_mqtt.h declare_mqtt_processloop
@copydoc MQTT_ProcessLoop
@page mqtt_receiveloop_function MQTT_ReceiveLoop
@snippet core_mqtt.h declare_mqtt_receiveloop
@copydoc MQTT_ReceiveLoop
@page mqtt_getpacketid_function MQTT_GetPacketId
@snippet core_mqtt.h declare_mqtt_getpacketid
@copydoc MQTT_GetPacketId
@page mqtt_getsubackstatuscodes_function MQTT_GetSubAckStatusCodes
@snippet core_mqtt.h declare_mqtt_getsubackstatuscodes
@copydoc MQTT_GetSubAckStatusCodes
@page mqtt_status_strerror_function MQTT_Status_strerror
@snippet core_mqtt.h declare_mqtt_status_strerror
@copydoc MQTT_Status_strerror
@page mqtt_publishtoresend_function MQTT_PublishToResend
@snippet core_mqtt_state.h declare_mqtt_publishtoresend
@copydoc MQTT_PublishToResend
@page mqtt_getconnectpacketsize_function MQTT_GetConnectPacketSize
@snippet core_mqtt_serializer.h declare_mqtt_getconnectpacketsize
@copydoc MQTT_GetConnectPacketSize
@page mqtt_serializeconnect_function MQTT_SerializeConnect
@snippet core_mqtt_serializer.h declare_mqtt_serializeconnect
@copydoc MQTT_SerializeConnect
@page mqtt_getsubscribepacketsize_function MQTT_GetSubscribePacketSize
@snippet core_mqtt_serializer.h declare_mqtt_getsubscribepacketsize
@copydoc MQTT_GetSubscribePacketSize
@page mqtt_serializesubscribe_function MQTT_SerializeSubscribe
@snippet core_mqtt_serializer.h declare_mqtt_serializesubscribe
@copydoc MQTT_SerializeSubscribe
@page mqtt_getunsubscribepacketsize_function MQTT_GetUnsubscribePacketSize
@snippet core_mqtt_serializer.h declare_mqtt_getunsubscribepacketsize
@copydoc MQTT_GetUnsubscribePacketSize
@page mqtt_serializeunsubscribe_function MQTT_SerializeUnsubscribe
@snippet core_mqtt_serializer.h declare_mqtt_serializeunsubscribe
@copydoc MQTT_SerializeUnsubscribe
@page mqtt_getpublishpacketsize_function MQTT_GetPublishPacketSize
@snippet core_mqtt_serializer.h declare_mqtt_getpublishpacketsize
@copydoc MQTT_GetPublishPacketSize
@page mqtt_serializepublish_function MQTT_SerializePublish
@snippet core_mqtt_serializer.h declare_mqtt_serializepublish
@copydoc MQTT_SerializePublish
@page mqtt_serializepublishheader_function MQTT_SerializePublishHeader
@snippet core_mqtt_serializer.h declare_mqtt_serializepublishheader
@copydoc MQTT_SerializePublishHeader
@page mqtt_serializeack_function MQTT_SerializeAck
@snippet core_mqtt_serializer.h declare_mqtt_serializeack
@copydoc MQTT_SerializeAck
@page mqtt_getdisconnectpacketsize_function MQTT_GetDisconnectPacketSize
@snippet core_mqtt_serializer.h declare_mqtt_getdisconnectpacketsize
@copydoc MQTT_GetDisconnectPacketSize
@page mqtt_serializedisconnect_function MQTT_SerializeDisconnect
@snippet core_mqtt_serializer.h declare_mqtt_serializedisconnect
@copydoc MQTT_SerializeDisconnect
@page mqtt_getpingreqpacketsize_function MQTT_GetPingreqPacketSize
@snippet core_mqtt_serializer.h declare_mqtt_getpingreqpacketsize
@copydoc MQTT_GetPingreqPacketSize
@page mqtt_serializepingreq_function MQTT_SerializePingreq
@snippet core_mqtt_serializer.h declare_mqtt_serializepingreq
@copydoc MQTT_SerializePingreq
@page mqtt_deserializepublish_function MQTT_DeserializePublish
@snippet core_mqtt_serializer.h declare_mqtt_deserializepublish
@copydoc MQTT_DeserializePublish
@page mqtt_deserializeack_function MQTT_DeserializeAck
@snippet core_mqtt_serializer.h declare_mqtt_deserializeack
@copydoc MQTT_DeserializeAck
@page mqtt_getincomingpackettypeandlength_function MQTT_GetIncomingPacketTypeAndLength
@snippet core_mqtt_serializer.h declare_mqtt_getincomingpackettypeandlength
@copydoc MQTT_GetIncomingPacketTypeAndLength
*/
/**
@defgroup mqtt_enum_types Enumerated Types
@brief Enumerated types of the MQTT library
*/
/**
@defgroup mqtt_callback_types Callback Types
@brief Callback function pointer types of the MQTT library
*/
/**
@defgroup mqtt_struct_types Parameter Structures
@brief Structures passed as parameters to [MQTT library functions](@ref mqtt_functions)
These structures are passed as parameters to library functions. Documentation for these structures will state the functions associated with each parameter structure and the purpose of each member.
*/
/**
@defgroup mqtt_basic_types Basic Types
@brief Primitive types of the MQTT library.
*/
/**
@defgroup mqtt_constants Constants
@brief Constants defined in the MQTT library
*/

View File

@ -0,0 +1,75 @@
/**
@page mqtt_porting Porting Guide
@brief Guide for porting MQTT to a new platform.
A port to a new platform must provide the following components:
1. [Configuration Macros](@ref mqtt_porting_config)
2. [Transport Interface](@ref mqtt_porting_transport)
3. [Time Function](@ref mqtt_porting_time)
@section mqtt_porting_config Configuration Macros
@brief Settings that must be set as macros in the config header `core_mqtt_config.h`, or passed in as compiler options.
@note If a custom configuration header `core_mqtt_config.h` is not provided, then the @ref MQTT_DO_NOT_USE_CUSTOM_CONFIG macro must be defined.
@see [Configurations](@ref core_mqtt_config)
The following macros can be configured for the managed MQTT library:
- @ref MQTT_PINGRESP_TIMEOUT_MS <br>
- @ref MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT
In addition, the following logging macros are used throughout the library:
- @ref LogError
- @ref LogWarn
- @ref LogInfo
- @ref LogDebug
@section mqtt_porting_transport Transport Interface
@brief The MQTT library relies on an underlying transport interface API that must be implemented
in order to send and receive packets on a network.
@see [Transport Interface](@ref mqtt_transport_interface)
The transport interface API used by MQTT is defined in @ref transport_interface.h.
A port must implement functions corresponding to the following functions pointers:
- [Transport Receive](@ref TransportRecv_t): A function to receive bytes from a network.
@code
int32_t (* TransportRecv_t )(
NetworkContext_t * pNetworkContext, void * pBuffer, size_t bytesToRecv
);
@endcode
- [Transport Send](@ref TransportSend_t): A function to send bytes over a network.
@code
int32_t (* TransportSend_t )(
NetworkContext_t * pNetworkContext, const void * pBuffer, size_t bytesToSend
);
@endcode
The above two functions take in a pointer to a @ref NetworkContext_t, the typename of a
`struct NetworkContext`. The NetworkContext struct must also be defined by the port, and
ought to contain any information necessary to send and receive data with the @ref TransportSend_t
and @ref TransportRecv_t implementations, respectively:
@code
struct NetworkContext {
// Fields necessary for the transport implementations, e.g. a TCP socket descriptor.
};
@endcode
@section mqtt_porting_time Time Function
@brief The MQTT library relies on a function to generate millisecond timestamps, for the
purpose of calculating durations and timeouts, as well as maintaining the keep-alive mechanism
of the MQTT protocol.
@see @ref MQTTGetCurrentTimeFunc_t
Platforms must supply a function capable of generating 32 bit timestamps of millisecond resolution.
These timestamps need not correspond with any real world clock; the only requirement is that the
difference between two timestamps must be an accurate representation of the duration between them,
in milliseconds.
@note Should the platform be incapable of providing millisecond timestamps, the port may instead
provide a function that always returns 0, or a strictly non-decreasing sequence. In this case, the
timeout values in all library calls to @ref MQTT_Connect, @ref MQTT_ProcessLoop, or @ref MQTT_ReceiveLoop
MUST be set to 0, resulting in loop functions running for a single iteration, and @ref MQTT_Connect
relying on @ref MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT to receive the CONNACK packet.
*/

View File

@ -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;
}

View File

@ -0,0 +1,111 @@
/**
@page mqtt_timeouts Timeouts in coreMQTT library
@brief Information about timeouts that coreMQTT library relies on.
The coreMQTT library relies on timeouts to handle MQTT keep-alive mechanism and Transport Send and Receive operations.
Timeouts must be configured correctly for ensuring the expected behavior of the application using the coreMQTT library.
The timeouts and the recommended configurations are listed below.
1. [Transport Send and Receive timeouts](@ref mqtt_timeouts_transport_send_receive)
2. [MQTT Keep Alive interval](@ref mqtt_timeouts_keep_alive)
3. [MQTT Ping Response timeout](@ref mqtt_timeouts_ping_response)
4. [MQTT Receive Polling timeout](@ref mqtt_timeouts_receive_polling)
5. [MQTT Send timeout](@ref mqtt_timeouts_send)
6. [Timeouts for MQTT_ProcessLoop and MQTT_ReceiveLoop APIs](@ref mqtt_timeouts_process_receive_loop)
7. [Timeout for MQTT_Connect](@ref mqtt_timeouts_connect)
@section mqtt_timeouts_transport_send_receive Transport Send and Receive timeouts
These are the network send and read operation blocking timeouts used by the implementation
of Transport Send and Transport Receive functions, respectively, that are supplied to the coreMQTT library.
Transport Send and Receive timeouts must be configured by the application for the Transport
interface implementation provided to the coreMQTT library. If it is essential to send more data than
the size of the TCP buffer, then the Transport Send timeout can be set to a bigger value than that of
cases in which size of the data to be sent is smaller than the TCP buffer, so as to efficiently wait for the
TCP buffer to be available to copy the data from MQTT buffers.
We recommend using a relatively smaller value for these timeouts as compared to the MQTT Keep Alive interval,
so as to make sure that an MQTT Control packet including an MQTT ping request packet can be sent to the Server
even within the Keep Alive interval, even if the Transport functions block for the maximum time.
@see [Transport Interface](@ref mqtt_transport_interface)
@section mqtt_timeouts_keep_alive MQTT Keep Alive interval
MQTT Keep Alive interval is the maximum time interval that is permitted to elapse between the point at which
the MQTT Client finishes transmitting one Control Packet and the point it starts sending the next. If the Server does not
receive a Control Packet from the Client within one and a half times the Keep Alive time period, it will disconnect
the MQTT connection to the Client.
If @ref mqtt_processloop_function function is used to manage keep alive in the application,
the MQTT Keep Alive interval must be configured to be a value larger than that of the Transport Send and Receive timeouts.
This is to make sure that a Control packet including an MQTT ping request packet can be sent to the Server even if
the Transport functions block for the maximum time. MQTT Keep Alive interval can be configured by setting the
`keepAliveIntervalSec` member of the [MQTTContext_t](@ref mqtt_struct_types) structure.
@see @ref mqtt_keepalive
@section mqtt_timeouts_ping_response MQTT Ping Response timeout
MQTT Ping Response timeout is the time to wait for a ping response to an MQTT ping request as part of the keep-alive
mechanism in the MQTT Client. This timeout can be configured independent of the Transport timeouts unlike the MQTT Keep Alive
interval, since this timeout only depends on the MQTT broker, the platform and the network latencies.
We recommend to choose a ping response timeout by experimenting with an MQTT application on a sample of devices and collecting the data
of latency for each ping response from the broker after a ping request is sent. A timeout value can then be chosen based on the statistical
measure suitable for the end application, such as 99th percentile or average.
MQTT Ping Response timeout can be set by defining the configuration @ref MQTT_PINGRESP_TIMEOUT_MS.
@section mqtt_timeouts_receive_polling MQTT Receive Polling timeout
MQTT Receive Polling timeout is the maximum duration between non-empty network reads while receiving an MQTT packet
via the @ref mqtt_processloop_function or @ref mqtt_receiveloop_function API functions. This timeout represents the maximum polling
duration that is allowed without any data reception from the network for the incoming packet.
It is important to note that having this timeout too short will result in MQTT being disconnected due to the possibility of partial data
being received. If you have small TCP buffers and a high latency network, the optimum value for the timeout can be surprisingly long.
In such cases, optimum value for the timeout can be better determined based on experimenting the MQTT applications with payloads
bigger than the TCP buffer. If a retry is required for a Transport Receive even after hitting a timeout of Transport Receive
without any data received, we recommend using a value larger than the Transport Receive timeout. If a dummy implementation of the
@ref MQTTGetCurrentTimeFunc_t timer function, that always returns 0, is used, then this timeout must be set to 0.
The MQTT Receive Polling timeout can be set by defining the configuration @ref MQTT_RECV_POLLING_TIMEOUT_MS.
@section mqtt_timeouts_send MQTT Send timeout
MQTT Send timeout is the maximum duration allowed to send an MQTT packet over the transport interface.
It is important to note that having this timeout too short will result in MQTT being disconnected due to the possibility
of partial data being sent. If you have small TCP buffers and a high latency network, the optimum value for the timeout
can be surprisingly long. In such cases, optimum value for the timeout can be better determined based on experimenting
the MQTT applications with payloads bigger than the TCP buffer. If a retry is required for a Transport Send even after
hitting a timeout of Transport Send before any data could be sent to transport layer, we recommend using a value larger
than the Transport Send timeout. If a dummy implementation of the @ref MQTTGetCurrentTimeFunc_t timer function,
that always returns 0, is used, then this timeout must be set to 0.
The MQTT Send timeout can be set by defining the configuration @ref MQTT_SEND_TIMEOUT_MS.
@section mqtt_timeouts_process_receive_loop Timeouts for MQTT_ProcessLoop and MQTT_ReceiveLoop APIs
This timeout is passed as an argument to @ref mqtt_processloop_function or @ref mqtt_receiveloop_function API functions.
It is the minimum time that the receive loop in these API functions will run, unless an error occurs. These APIs may be blocked
for more time than this timeout, since the APIs will attempt to send and receive MQTT packets to the network using the
Transport implementation. The maximum time spent on Transport functions for send and receive depends on the Transport Send and
Receive timeouts and the MQTT Receive Polling timeouts as explained in the descriptions of these timeouts above.
Passing a timeout value of 0 will run these APIs for a single iteration. The other timeouts mentioned thus far ensure you don't
disconnect the MQTT just because the network is slow or buffers get full. They are necessary because coreMQTT has no 'memory' of
being half way through a packet and will just error and disconnect if you don't give enough time for incoming or outgoing packet delivery.
That means, especially in multi-threaded application, the process loop timeout can be zero.
@ref mqtt_processloop_function API can be used to manage the MQTT keep-alive mechanism and if used, application must invoke this API
faster than the MQTT Keep Alive interval. If a dummy @ref MQTTGetCurrentTimeFunc_t was passed to @ref mqtt_init_function, then the keep-alive mechanism is not supported by the @ref mqtt_processloop_function API; instead the @ref mqtt_receiveloop_function should be used.
@see @ref mqtt_receivetimeout
@section mqtt_timeouts_connect Timeout for MQTT_Connect
This timeout is passed as an argument to @ref mqtt_connect_function. It is the maximum time to wait for an MQTT CONNACK packet. If this value is
set to 0, then instead of a time-based loop, it will attempt to call the Transport Receive function up to a maximum number of retries,
which is defined by @ref MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT.
We recommend to choose a timeout for @ref mqtt_connect_function by experimenting with an MQTT application on a sample of devices and
collecting the data of latency for each CONNACK packet received from the broker after an MQTT CONNECT packet is sent. A timeout value can then be chosen
based on the statistical measure suitable for the end application, such as 99th percentile or average.
@see @ref mqtt_receivetimeout
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

View File

@ -0,0 +1,21 @@
@startuml
skinparam dpi 300
skinparam ArrowFontSize 18
start
: Send CONNECT packet;
: count = 0;
repeat
: Receive single byte;
repeat while ( No network data available AND \n retry count < MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT) is (yes)
-> no or timeout == 0;
repeat
: Get rest of CONNACK packet;
note left: Retry zero byte reads for maximum period \nof **MQTT_RECV_POLLING_TIMEOUT_MS**
repeat while( Received complete packet? ) is ( no )
: Deserialize CONNACK packet;
stop
@enduml

View File

@ -0,0 +1,32 @@
@startuml
skinparam dpi 300
skinparam ArrowFontSize 18
start
repeat
: Receive single byte;
if( read successful? ) then (yes)
repeat
: Get rest of packet;
note left: Retry zero byte reads for maximum period \nof **MQTT_RECV_POLLING_TIMEOUT_MS**
repeat while( Received complete packet? ) is ( no )
: Deserialize packet;
if ( Need to send ACK response? ) then (yes)
repeat
: Send ACK packet;
note left: Retry zero byte sends for maximum period \nof **MQTT_SEND_RETRY_TIMEOUT_MS**
repeat while( Sent complete packet? ) is ( no )
else (no)
endif
: Invoke Application callback;
else (no)
: Manage Keep-Alive;
endif
repeat while (**timeout** reached) is (no)
-> yes or timeout == 0;
stop
@enduml

View File

@ -0,0 +1,30 @@
@startuml
skinparam dpi 300
skinparam ArrowFontSize 18
start
repeat
: Receive single byte;
if( read successful? ) then (yes)
repeat
: Get rest of packet;
note left: Retry zero byte reads for maximum period \nof **MQTT_RECV_POLLING_TIMEOUT_MS**
repeat while( Received complete packet? ) is ( no )
: Deserialize packet;
if ( Need to send ACK response? ) then (yes)
repeat
: Send ACK packet;
note left: Retry zero byte sends for maximum period \nof **MQTT_SEND_RETRY_TIMEOUT_MS**
repeat while( Sent complete packet? ) is ( no )
else (no)
endif
else (no)
endif
repeat while (**timeout** reached) is (no)
-> yes or timeout == 0;
stop
@enduml

View File

@ -0,0 +1,439 @@
ack
acked
acks
addrecord
addtogroup
alt
ansi
api
apis
app
aws
bool
br
bufferlength
bytesorerror
bytesreceived
bytesrecvd
bytesremaining
bytessent
bytessentthisvector
bytestoread
bytestoreceive
bytestorecv
bytestosend
bytestowrite
calculatestateack
calculatestatepublish
calltlsrecvfunc
cb
cbmc
chk
cleansession
clientidentifierlength
cmock
colspan
com
cond
config
configpagestyle
configs
connack
connectinfo
connectpacketsize
const
copydoc
coremqtt
coverity
csdk
css
currentstate
de
defgroup
defragmenting
deserialization
deserializationresult
deserialize
deserializeack
deserialized
deserializepublish
deserializer
deserializers
deserializestatus
deserializing
didn
disconnectpacketsize
doesn
doxygen
dup
emptyindex
endcode
endcond
endif
enum
enums
eventcallback
expectprocessloopcalls
filterindex
findinrecord
fixedbuffer
fn
freertos
gcc
getconnectpacketsize
getdisconnectpacketsize
getincomingpackettypeandlength
getnewpacketid
getpacketid
getpingreqpacketsize
getpublish
getpublishpacketsize
getsubackstatuscodes
getsubscribepacketsize
gettime
gettimefunction
gettimestampms
getunsubscribepacketsize
github
handleincomingack
handleincomingpublish
handlekeepalive
hasn
headersize
html
http
https
ifdef
ifndef
img
inc
incomingpacket
incomingpublish
incomingpublishcount
incomingpublishrecords
ingroup
init
initializeconnectinfo
initializesubscribeinfo
initializewillinfo
int
io
iot
ioveccount
ip
isn
iso
keepaliveintervalsec
keepalivems
keepaliveseconds
lastpackettxtime
linux
logdebug
logerror
loginfo
logwarn
lsb
lwt
mainpage
malloc
managekeepalive
matchtopic
maxrecordcount
md
mdash
memcpy
memset
metadata
mib
min
minimise
misra
mit
modifyincomingpacket
mq
mqtt
mqttbadparameter
mqttbadresponse
mqttconnected
mqttconnectinfo
mqttcontext
mqttdeserializedinfo
mqtteventcallback
mqttfixedbuffer
mqttgetcurrenttimefunc
mqttillegalstate
mqttkeepalivetimeout
mqttneedmorebytes
mqttnodataavailable
mqttnomemory
mqttnotconnected
mqttpacketinfo
mqttpuback
mqttpubackpending
mqttpubacksend
mqttpubacktype
mqttpubcomp
mqttpubcomppending
mqttpubcompsend
mqttpublishdone
mqttpublishinfo
mqttpublishsend
mqttpublishstate
mqttpubrec
mqttpubrecpending
mqttpubrecsend
mqttpubrel
mqttpubrelpending
mqttpubrelsend
mqttqos
mqttrecvfailed
mqttsendfailed
mqttserverrefused
mqttsocket
mqttstatecollision
mqttstatecursor
mqttstatenull
mqttstateoperation
mqttstatus
mqttsubackfailure
mqttsubackstatus
mqttsubacksuccessqos
mqttsubscribeinfo
mqttsuccess
msb
mutex
mynetworkrecvimplementation
mynetworksendimplementation
mytcpsocketcontext
mytlscontext
networkbuffer
networkcontext
networkinterfacereceivestub
networkinterfacesendstub
networkrecv
networksend
newstate
nextpacketid
noninfringement
numcodes
optype
org
os
outgoingpublishes
outgoingpublishcount
outgoingpublishrecords
packetid
packetidentifier
packetsize
packettype
param
paramters
passwordlength
payloadlength
pbuffer
pbuffertosend
pclientidentifier
pcodes
pconnack
pconnectinfo
pcontext
pcurrentstate
pcursor
pdeserializedinfo
pdestination
pexpectparams
pfilter
pfilterindex
pfixedbuffer
pheadersize
pincomingpacket
pincomingpublishrecords
pindex
pingreq
pingreqs
pingreqsendtimems
pingresp
pingresps
piovec
pismatch
plaintext
pmatch
pmessage
pmqttcontext
pmqttheader
pnameindex
pnetworkbuffer
pnetworkcontext
pnetworkinterface
pnewstate
png
posix
poutgoingpublishrecords
ppacketid
ppacketidentifier
ppacketinfo
ppacketsize
ppassword
ppayload
ppayloadsize
ppayloadstart
ppingresp
ppubinfo
ppublishinfo
pqos
pre
premainingdata
premaininglength
presendpublish
printf
processloop
processloopstatus
psessionpresent
psource
pstate
pstatusstart
psuback
psubackpacket
psubscribeinfo
psubscribes
psubscription
psubscriptionlist
ptopic
ptopicfilter
ptopicname
ptotalmessagelength
ptr
ptransport
ptransportinterface
puback
pubacks
pubcomp
pubcomps
publishflags
publishinfo
publishpacketid
publishstate
publishtoresend
pubrec
pubrecs
pubrel
pubrels
pubreltoresend
pusername
pwillinfo
qos
readfunc
receiveincomingpacket
receiveloop
receivepacket
recordcount
recordindex
recv
recvexact
recvfunc
reestablishment
remaininglength
remainingtime
remainingtimems
resending
reservestate
responsecode
rm
rx
sdk
searchstates
sendpacket
sendpublish
sendpublishacks
serializeack
serializeconnect
serializeconnectpacket
serializedisconnect
serailizedlength
serializedpasswordlength
serializedpayloadlength
serializedtopiclength
serializedusernamelength
serializepayload
serializepingreq
serializepublish
serializepublishheader
serializestatus
serializesubscribe
serializeunsubscribe
sessionpresent
shoulddelete
shouldn
sizeof
someclientid
somenetworkinterface
somepassword
sometransportcontext
someusername
sourcelength
spdx
src
stateafterdeserialize
stateafterserialize
statuscount
strerror
strlen
struct
structs
suback
sublicense
subscribeinfo
subscriptioncount
subscriptionlist
subscriptiontype
sys
tcp
tcpsocket
tcpsocketcontext
td
testcase
timeoutms
tls
tlscontext
tlsrecv
tlsrecvcount
tlssend
toolchain
topicfilterlength
topicnamelength
totalmessagelength
tr
transportcallback
transportinterface
transportpage
transportrecv
transportsectionimplementation
transportsectionoverview
transportsend
transportsendnobytes
transportstruct
tx
typename
uint
un
unacked
unsuback
unsubscribelist
updatedlength
updatestateack
updatestatepublish
updatestatestatus
usercallback
usernamelength
utf
validatesubscribeunsubscribeparams
validator
waitingforpingresp
willinfo
writev
xa
xb
xc
xd
xe
xf

View File

@ -0,0 +1,5 @@
name : "coreMQTT"
version: "v2.1.1"
description: |
"Client implementation of the MQTT 3.1.1 specification for embedded devices.\n"
license: "MIT"

View File

@ -0,0 +1,20 @@
# 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.
# MQTT library source files.
set( MQTT_SOURCES
"${CMAKE_CURRENT_LIST_DIR}/source/core_mqtt.c"
"${CMAKE_CURRENT_LIST_DIR}/source/core_mqtt_state.c" )
# MQTT Serializer library source files.
set( MQTT_SERIALIZER_SOURCES
"${CMAKE_CURRENT_LIST_DIR}/source/core_mqtt_serializer.c" )
# MQTT library Public Include directories.
set( MQTT_INCLUDE_PUBLIC_DIRS
"${CMAKE_CURRENT_LIST_DIR}/source/include"
"${CMAKE_CURRENT_LIST_DIR}/source/interface" )

View File

@ -0,0 +1,13 @@
black
check-manifest
cookiecutter
flake8
mypy
nox
pre-commit
pybind11
pylint
pytest
pyyaml
setuptools
setuptools-rust

View File

@ -0,0 +1,43 @@
SPDXVersion: SPDX-2.2
DataLicense: CC0-1.0
SPDXID: SPDXRef-DOCUMENT
DocumentName: coreMQTT
DocumentNamespace: https://github.com/FreeRTOS/coreMQTT/blob/v2.1.1/sbom.spdx
Creator: Amazon Web Services
Created: 2022-11-10T04:30:20Z
CreatorComment: NOASSERTION
DocumentComment: NOASSERTION
PackageName: coreMQTT
SPDXID: SPDXRef-Package-coreMQTT
PackageVersion: v2.1.1
PackageDownloadLocation: https://github.com/FreeRTOS/coreMQTT/tree/v2.1.1
PackageLicenseConcluded: MIT
FilesAnalyzed: True
PackageVerificationCode: 044c60b9b98c79546cc9c14b6e53cade1ba30979
PackageCopyrightText: NOASSERTION
PackageSummary: NOASSERTION
PackageDescription: "Client implementation of the MQTT 3.1.1 specification for embedded devices.\n"
FileName: ./core_mqtt_state.c
SPDXID: SPDXRef-File-core_mqtt_state.c
FileChecksum: SHA1: 235a814c7d390bb4115fffa88da6c53440517141
LicenseConcluded: MIT
FileCopyrightText: NOASSERTION
FileComment: NOASSERTION
FileName: ./core_mqtt.c
SPDXID: SPDXRef-File-core_mqtt.c
FileChecksum: SHA1: 054500b1b15a01e3f068834c2e1fca5951114afc
LicenseConcluded: MIT
FileCopyrightText: NOASSERTION
FileComment: NOASSERTION
FileName: ./core_mqtt_serializer.c
SPDXID: SPDXRef-File-core_mqtt_serializer.c
FileChecksum: SHA1: 5c4805ca90f93671f2cf2d78cc85862583cdb57f
LicenseConcluded: MIT
FileCopyrightText: NOASSERTION
FileComment: NOASSERTION

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,204 @@
/*
* coreMQTT v2.1.1
* Copyright (C) 2022 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 core_mqtt_config_defaults.h
* @brief This represents the default values for the configuration macros
* for the MQTT library.
*
* @note This file SHOULD NOT be modified. If custom values are needed for
* any configuration macro, a core_mqtt_config.h file should be provided to
* the MQTT library to override the default values defined in this file.
* To use the custom config file, the MQTT_DO_NOT_USE_CUSTOM_CONFIG preprocessor
* macro SHOULD NOT be set.
*/
#ifndef CORE_MQTT_CONFIG_DEFAULTS_H_
#define CORE_MQTT_CONFIG_DEFAULTS_H_
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/* MQTT_DO_NOT_USE_CUSTOM_CONFIG allows building the MQTT library
* without a custom config. If a custom config is provided, the
* MQTT_DO_NOT_USE_CUSTOM_CONFIG macro should not be defined. */
#ifndef MQTT_DO_NOT_USE_CUSTOM_CONFIG
/* Include custom config file before other headers. */
#include "core_mqtt_config.h"
#endif
/* The macro definition for MQTT_DO_NOT_USE_CUSTOM_CONFIG is for Doxygen
* documentation only. */
/**
* @brief Define this macro to build the MQTT library without the custom config
* file core_mqtt_config.h.
*
* Without the custom config, the MQTT library builds with
* default values of config macros defined in core_mqtt_config_defaults.h file.
*
* If a custom config is provided, then MQTT_DO_NOT_USE_CUSTOM_CONFIG should not
* be defined.
*/
#ifdef DOXYGEN
#define MQTT_DO_NOT_USE_CUSTOM_CONFIG
#endif
/**
* @ingroup mqtt_constants
* @brief Maximum number of vectors in subscribe and unsubscribe packet.
*/
#ifndef MQTT_SUB_UNSUB_MAX_VECTORS
#define MQTT_SUB_UNSUB_MAX_VECTORS ( 4U )
#endif
/**
* @brief The number of retries for receiving CONNACK.
*
* The MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT will be used only when the
* timeoutMs parameter of #MQTT_Connect is passed as 0 . The transport
* receive for CONNACK will be retried MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT
* times before timing out. A value of 0 for this config will cause the
* transport receive for CONNACK to be invoked only once.
*
* <b>Possible values:</b> Any positive 16 bit integer. <br>
* <b>Default value:</b> `5`
*/
#ifndef MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT
/* Default value for the CONNACK receive retries. */
#define MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT ( 5U )
#endif
/**
* @brief Maximum number of milliseconds to wait for a ping response to a ping
* request as part of the keep-alive mechanism.
*
* If a ping response is not received before this timeout, then
* #MQTT_ProcessLoop will return #MQTTKeepAliveTimeout.
*
* @note If this value is more than half of the keep alive interval, and the
* server does not receive the previous ping request, then it is likely that the
* server will disconnect the client before #MQTTKeepAliveTimeout can be returned.
*
* @note If a dummy implementation of the #MQTTGetCurrentTimeFunc_t timer function,
* is supplied to the library, then the keep-alive mechanism is not supported by the
* #MQTT_ProcessLoop API function. In that case, the value of #MQTT_PINGRESP_TIMEOUT_MS
* is irrelevant to the behavior of the library.
*
* <b>Possible values:</b> Any positive integer up to SIZE_MAX. <br>
* <b>Default value:</b> `5000`
*/
#ifndef MQTT_PINGRESP_TIMEOUT_MS
/* Wait 5 seconds by default for a ping response. */
#define MQTT_PINGRESP_TIMEOUT_MS ( 5000U )
#endif
/**
* @brief Maximum number of milliseconds of TX inactivity to wait
* before initiating a PINGREQ
*
* @note If this value is less than the keep alive interval than
* it will be used instead.
*
* <b>Possible values:</b> Any positive integer up to SIZE_MAX. <br>
* <b>Default value:</b> '30000'
*/
#ifndef PACKET_TX_TIMEOUT_MS
#define PACKET_TX_TIMEOUT_MS ( 30000U )
#endif
/**
* @brief Maximum number of milliseconds of RX inactivity to wait
* before initiating a PINGREQ
*
* <b>Possible values:</b> Any positive integer up to SIZE_MAX. <br>
* <b>Default value:</b> '30000'
*
*/
#ifndef PACKET_RX_TIMEOUT_MS
#define PACKET_RX_TIMEOUT_MS ( 30000U )
#endif
/**
* @brief The maximum duration between non-empty network reads while
* receiving an MQTT packet via the #MQTT_ProcessLoop or #MQTT_ReceiveLoop
* API functions.
*
* When an incoming MQTT packet is detected, the transport receive function
* may be called multiple times until all of the expected number of bytes of the
* packet are received. This timeout represents the maximum polling duration that
* is allowed without any data reception from the network for the incoming packet.
*
* If the timeout expires, the #MQTT_ProcessLoop and #MQTT_ReceiveLoop functions
* return #MQTTRecvFailed.
*
* @note If a dummy implementation of the #MQTTGetCurrentTimeFunc_t timer function,
* is supplied to the library, then #MQTT_RECV_POLLING_TIMEOUT_MS MUST be set to 0.
*
* <b>Possible values:</b> Any positive 32 bit integer. Recommended to use a
* small timeout value. <br>
* <b>Default value:</b> `10`
*
*/
#ifndef MQTT_RECV_POLLING_TIMEOUT_MS
#define MQTT_RECV_POLLING_TIMEOUT_MS ( 10U )
#endif
/**
* @brief The maximum duration allowed to send an MQTT packet over the transport
* interface.
*
* When sending an MQTT packet, the transport send or writev functions may be
* called multiple times until all of the required number of bytes are sent.
* This timeout represents the maximum duration that is allowed to send the MQTT
* packet while calling the transport send or writev functions.
*
* If the timeout expires, #MQTTSendFailed will be returned by the public API
* functions.
*
* @note If a dummy implementation of the #MQTTGetCurrentTimeFunc_t timer function,
* is supplied to the library, then #MQTT_SEND_TIMEOUT_MS MUST be set to 0.
*
* <b>Possible values:</b> Any positive 32 bit integer. <br>
* <b>Default value:</b> `20000`
*
*/
#ifndef MQTT_SEND_TIMEOUT_MS
#define MQTT_SEND_TIMEOUT_MS ( 20000U )
#endif
#ifdef MQTT_SEND_RETRY_TIMEOUT_MS
#error MQTT_SEND_RETRY_TIMEOUT_MS is deprecated. Instead use MQTT_SEND_TIMEOUT_MS.
#endif
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* ifndef CORE_MQTT_CONFIG_DEFAULTS_H_ */

View File

@ -0,0 +1,132 @@
/*
* coreMQTT v2.1.1
* Copyright (C) 2022 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 core_mqtt_default_logging.h
* @brief This represents the default values for the logging macros for the MQTT
* library.
*
* @note This file SHOULD NOT be modified. If custom values are needed for
* any configuration macro, a core_mqtt_config.h file should be provided to
* the MQTT library to override the default values defined in this file.
* To use the custom config file, the MQTT_DO_NOT_USE_CUSTOM_CONFIG preprocessor
* macro SHOULD NOT be set.
*/
#ifndef CORE_MQTT_DEFAULT_LOGGING_H_
#define CORE_MQTT_DEFAULT_LOGGING_H_
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/**
* @brief Macro that is called in the MQTT library for logging "Error" level
* messages.
*
* To enable error level logging in the MQTT library, this macro should be mapped to the
* application-specific logging implementation that supports error logging.
*
* @note This logging macro is called in the MQTT library with parameters wrapped in
* double parentheses to be ISO C89/C90 standard compliant. For a reference
* POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the
* logging-stack in demos folder of the
* [AWS IoT Embedded C SDK repository](https://github.com/aws/aws-iot-device-sdk-embedded-C).
*
* <b>Default value</b>: Error logging is turned off, and no code is generated for calls
* to the macro in the MQTT library on compilation.
*/
#ifndef LogError
#define LogError( message )
#endif
/**
* @brief Macro that is called in the MQTT library for logging "Warning" level
* messages.
*
* To enable warning level logging in the MQTT library, this macro should be mapped to the
* application-specific logging implementation that supports warning logging.
*
* @note This logging macro is called in the MQTT library with parameters wrapped in
* double parentheses to be ISO C89/C90 standard compliant. For a reference
* POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the
* logging-stack in demos folder of the
* [AWS IoT Embedded C SDK repository](https://github.com/aws/aws-iot-device-sdk-embedded-C/).
*
* <b>Default value</b>: Warning logs are turned off, and no code is generated for calls
* to the macro in the MQTT library on compilation.
*/
#ifndef LogWarn
#define LogWarn( message )
#endif
/**
* @brief Macro that is called in the MQTT library for logging "Info" level
* messages.
*
* To enable info level logging in the MQTT library, this macro should be mapped to the
* application-specific logging implementation that supports info logging.
*
* @note This logging macro is called in the MQTT library with parameters wrapped in
* double parentheses to be ISO C89/C90 standard compliant. For a reference
* POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the
* logging-stack in demos folder of the
* [AWS IoT Embedded C SDK repository](https://github.com/aws/aws-iot-device-sdk-embedded-C/).
*
* <b>Default value</b>: Info logging is turned off, and no code is generated for calls
* to the macro in the MQTT library on compilation.
*/
#ifndef LogInfo
#define LogInfo( message )
#endif
/**
* @brief Macro that is called in the MQTT library for logging "Debug" level
* messages.
*
* To enable debug level logging from MQTT library, this macro should be mapped to the
* application-specific logging implementation that supports debug logging.
*
* @note This logging macro is called in the MQTT library with parameters wrapped in
* double parentheses to be ISO C89/C90 standard compliant. For a reference
* POSIX implementation of the logging macros, refer to core_mqtt_config.h files, and the
* logging-stack in demos folder of the
* [AWS IoT Embedded C SDK repository](https://github.com/aws/aws-iot-device-sdk-embedded-C/).
*
* <b>Default value</b>: Debug logging is turned off, and no code is generated for calls
* to the macro in the MQTT library on compilation.
*/
#ifndef LogDebug
#define LogDebug( message )
#endif
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* ifndef CORE_MQTT_DEFAULT_LOGGING_H_ */

View File

@ -0,0 +1,310 @@
/*
* coreMQTT v2.1.1
* Copyright (C) 2022 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 core_mqtt_state.h
* @brief Function to keep state of MQTT PUBLISH packet deliveries.
*/
#ifndef CORE_MQTT_STATE_H
#define CORE_MQTT_STATE_H
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
#include "core_mqtt.h"
/**
* @ingroup mqtt_constants
* @brief Initializer value for an #MQTTStateCursor_t, indicating a search
* should start at the beginning of a state record array
*/
#define MQTT_STATE_CURSOR_INITIALIZER ( ( size_t ) 0 )
/**
* @ingroup mqtt_basic_types
* @brief Cursor for iterating through state records.
*/
typedef size_t MQTTStateCursor_t;
/**
* @cond DOXYGEN_IGNORE
* Doxygen should ignore this section, this enum is private.
*
* @brief Value indicating either send or receive.
*/
typedef enum MQTTStateOperation
{
MQTT_SEND,
MQTT_RECEIVE
} MQTTStateOperation_t;
/** @endcond */
/**
* @fn MQTTStatus_t MQTT_ReserveState( const MQTTContext_t * pMqttContext, uint16_t packetId, MQTTQoS_t qos );
* @brief Reserve an entry for an outgoing QoS 1 or Qos 2 publish.
*
* @param[in] pMqttContext Initialized MQTT context.
* @param[in] packetId The ID of the publish packet.
* @param[in] qos 1 or 2.
*
* @return MQTTSuccess, MQTTNoMemory, or MQTTStateCollision.
*/
/**
* @cond DOXYGEN_IGNORE
* Doxygen should ignore this definition, this function is private.
*/
MQTTStatus_t MQTT_ReserveState( const MQTTContext_t * pMqttContext,
uint16_t packetId,
MQTTQoS_t qos );
/** @endcond */
/**
* @fn MQTTPublishState_t MQTT_CalculateStatePublish( MQTTStateOperation_t opType, MQTTQoS_t qos )
* @brief Calculate the new state for a publish from its qos and operation type.
*
* @param[in] opType Send or Receive.
* @param[in] qos 0, 1, or 2.
*
* @return The calculated state.
*/
/**
* @cond DOXYGEN_IGNORE
* Doxygen should ignore this definition, this function is private.
*/
MQTTPublishState_t MQTT_CalculateStatePublish( MQTTStateOperation_t opType,
MQTTQoS_t qos );
/** @endcond */
/**
* @fn MQTTStatus_t MQTT_UpdateStatePublish( const MQTTContext_t * pMqttContext, uint16_t packetId, MQTTStateOperation_t opType, MQTTQoS_t qos, MQTTPublishState_t * pNewState );
* @brief Update the state record for a PUBLISH packet.
*
* @param[in] pMqttContext Initialized MQTT context.
* @param[in] packetId ID of the PUBLISH packet.
* @param[in] opType Send or Receive.
* @param[in] qos 0, 1, or 2.
* @param[out] pNewState Updated state of the publish.
*
* @return #MQTTBadParameter, #MQTTIllegalState, #MQTTStateCollision or
* #MQTTSuccess.
*/
/**
* @cond DOXYGEN_IGNORE
* Doxygen should ignore this definition, this function is private.
*/
MQTTStatus_t MQTT_UpdateStatePublish( const MQTTContext_t * pMqttContext,
uint16_t packetId,
MQTTStateOperation_t opType,
MQTTQoS_t qos,
MQTTPublishState_t * pNewState );
/** @endcond */
/**
* @fn MQTTStatus_t MQTT_RemoveStateRecord( const MQTTContext_t * pMqttContext, uint16_t packetId );
* @brief Remove the state record for a PUBLISH packet.
*
* @param[in] pMqttContext Initialized MQTT context.
* @param[in] packetId ID of the PUBLISH packet.
*
* @return #MQTTBadParameter or #MQTTSuccess.
*/
/**
* @cond DOXYGEN_IGNORE
* Doxygen should ignore this definition, this function is private.
*/
MQTTStatus_t MQTT_RemoveStateRecord( const MQTTContext_t * pMqttContext,
uint16_t packetId );
/** @endcond */
/**
* @fn MQTTPublishState_t MQTT_CalculateStateAck( MQTTPubAckType_t packetType, MQTTStateOperation_t opType, MQTTQoS_t qos );
* @brief Calculate the state from a PUBACK, PUBREC, PUBREL, or PUBCOMP.
*
* @param[in] packetType PUBACK, PUBREC, PUBREL, or PUBCOMP.
* @param[in] opType Send or Receive.
* @param[in] qos 1 or 2.
*
* @return The calculated state.
*/
/**
* @cond DOXYGEN_IGNORE
* Doxygen should ignore this definition, this function is private.
*/
MQTTPublishState_t MQTT_CalculateStateAck( MQTTPubAckType_t packetType,
MQTTStateOperation_t opType,
MQTTQoS_t qos );
/** @endcond */
/**
* @fn MQTTStatus_t MQTT_UpdateStateAck( const MQTTContext_t * pMqttContext, uint16_t packetId, MQTTPubAckType_t packetType, MQTTStateOperation_t opType, MQTTPublishState_t * pNewState );
* @brief Update the state record for an ACKed publish.
*
* @param[in] pMqttContext Initialized MQTT context.
* @param[in] packetId ID of the ack packet.
* @param[in] packetType PUBACK, PUBREC, PUBREL, or PUBCOMP.
* @param[in] opType Send or Receive.
* @param[out] pNewState Updated state of the publish.
*
* @return #MQTTBadParameter if an invalid parameter is passed;
* #MQTTBadResponse if the packet from the network is not found in the records;
* #MQTTIllegalState if the requested update would result in an illegal transition;
* #MQTTSuccess otherwise.
*/
/**
* @cond DOXYGEN_IGNORE
* Doxygen should ignore this definition, this function is private.
*/
MQTTStatus_t MQTT_UpdateStateAck( const MQTTContext_t * pMqttContext,
uint16_t packetId,
MQTTPubAckType_t packetType,
MQTTStateOperation_t opType,
MQTTPublishState_t * pNewState );
/** @endcond */
/**
* @fn uint16_t MQTT_PubrelToResend( const MQTTContext_t * pMqttContext, MQTTStateCursor_t * pCursor, MQTTPublishState_t * pState );
* @brief Get the packet ID of next pending PUBREL ack to be resent.
*
* This function will need to be called to get the packet for which a PUBREL
* need to be sent when a session is reestablished. Calling this function
* repeatedly until packet id is 0 will give all the packets for which
* a PUBREL need to be resent in the correct order.
*
* @param[in] pMqttContext Initialized MQTT context.
* @param[in,out] pCursor Index at which to start searching.
* @param[out] pState State indicating that PUBREL packet need to be sent.
*/
/**
* @cond DOXYGEN_IGNORE
* Doxygen should ignore this definition, this function is private.
*/
uint16_t MQTT_PubrelToResend( const MQTTContext_t * pMqttContext,
MQTTStateCursor_t * pCursor,
MQTTPublishState_t * pState );
/** @endcond */
/**
* @brief Get the packet ID of next pending publish to be resent.
*
* This function will need to be called to get the packet for which a publish
* need to be sent when a session is reestablished. Calling this function
* repeatedly until packet id is 0 will give all the packets for which
* a publish need to be resent in the correct order.
*
* @param[in] pMqttContext Initialized MQTT context.
* @param[in,out] pCursor Index at which to start searching.
*
* <b>Example</b>
* @code{c}
*
* // For this example assume this function returns an outgoing unacknowledged
* // QoS 1 or 2 publish from its packet identifier.
* MQTTPublishInfo_t * getPublish( uint16_t packetID );
*
* // Variables used in this example.
* MQTTStatus_t status;
* MQTTStateCursor_t cursor = MQTT_STATE_CURSOR_INITIALIZER;
* bool sessionPresent;
* uint16_t packetID;
* MQTTPublishInfo_t * pResendPublish = NULL;
* MQTTConnectInfo_t connectInfo = { 0 };
*
* // This is assumed to have been initialized before the call to MQTT_Connect().
* MQTTContext_t * pContext;
*
* // Set clean session to false to attempt session resumption.
* connectInfo.cleanSession = false;
* connectInfo.pClientIdentifier = "someClientID";
* connectInfo.clientIdentifierLength = strlen( connectInfo.pClientIdentifier );
* connectInfo.keepAliveSeconds = 60;
* // Optional connect parameters are not relevant to this example.
*
* // Create an MQTT connection. Use 100 milliseconds as a timeout.
* status = MQTT_Connect( pContext, &connectInfo, NULL, 100, &sessionPresent );
*
* if( status == MQTTSuccess )
* {
* if( sessionPresent )
* {
* // Loop while packet ID is nonzero.
* while( ( packetID = MQTT_PublishToResend( pContext, &cursor ) ) != 0 )
* {
* // Assume this function will succeed.
* pResendPublish = getPublish( packetID );
* // Set DUP flag.
* pResendPublish->dup = true;
* status = MQTT_Publish( pContext, pResendPublish, packetID );
*
* if( status != MQTTSuccess )
* {
* // Application can decide how to handle a failure.
* }
* }
* }
* else
* {
* // The broker did not resume a session, so we can clean up the
* // list of outgoing publishes.
* }
* }
* @endcode
*/
/* @[declare_mqtt_publishtoresend] */
uint16_t MQTT_PublishToResend( const MQTTContext_t * pMqttContext,
MQTTStateCursor_t * pCursor );
/* @[declare_mqtt_publishtoresend] */
/**
* @fn const char * MQTT_State_strerror( MQTTPublishState_t state );
* @brief State to string conversion for state engine.
*
* @param[in] state The state to convert to a string.
*
* @return The string representation of the state.
*/
/**
* @cond DOXYGEN_IGNORE
* Doxygen should ignore this definition, this function is private.
*/
const char * MQTT_State_strerror( MQTTPublishState_t state );
/** @endcond */
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* ifndef CORE_MQTT_STATE_H */

View File

@ -0,0 +1,30 @@
#ifndef _STDBOOL_H
#define _STDBOOL_H
/*******************************************************************************
* This file contains the definitions specified in stdbool.h. It is provided to
* allow the library to be built using compilers that do not provide their own
* stdbool.h defintion.
*
* 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 files,
* for example passed using gcc's "-I" or "-isystem" options.
*
* 2) Rename the copied file stdbool.h.
*
*/
#ifndef __cplusplus
/* _Bool was introduced in C99. */
#define bool int
#define false 0
#define true 1
#endif
#define __bool_true_false_are_defined 1
#endif /* _STDBOOL_H */

View File

@ -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 */

View File

@ -0,0 +1,316 @@
/*
* coreMQTT v2.1.1
* Copyright (C) 2022 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 transport_interface.h
* @brief Transport interface definitions to send and receive data over the
* network.
*/
#ifndef TRANSPORT_INTERFACE_H_
#define TRANSPORT_INTERFACE_H_
#include <stdint.h>
#include <stddef.h>
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/**
* @transportpage
* @brief The transport interface definition.
*
* @transportsectionoverview
*
* The transport interface is a set of APIs that must be implemented using an
* external transport layer protocol. The transport interface is defined in
* @ref transport_interface.h. This interface allows protocols like MQTT and
* HTTP to send and receive data over the transport layer. This
* interface does not handle connection and disconnection to the server of
* interest. The connection, disconnection, and other transport settings, like
* timeout and TLS setup, must be handled in the user application.
* <br>
*
* The functions that must be implemented are:<br>
* - [Transport Receive](@ref TransportRecv_t)
* - [Transport Send](@ref TransportSend_t)
*
* Each of the functions above take in an opaque context @ref NetworkContext_t.
* The functions above and the context are also grouped together in the
* @ref TransportInterface_t structure:<br><br>
* @snippet this define_transportinterface
* <br>
*
* @transportsectionimplementation
*
* The following steps give guidance on implementing the transport interface:
*
* -# Implementing @ref NetworkContext_t<br><br>
* @snippet this define_networkcontext
* <br>
* @ref NetworkContext_t is the incomplete type <b>struct NetworkContext</b>.
* The implemented struct NetworkContext must contain all of the information
* that is needed to receive and send data with the @ref TransportRecv_t
* and the @ref TransportSend_t implementations.<br>
* In the case of TLS over TCP, struct NetworkContext is typically implemented
* with the TCP socket context and a TLS context.<br><br>
* <b>Example code:</b>
* @code{c}
* struct NetworkContext
* {
* struct MyTCPSocketContext tcpSocketContext;
* struct MyTLSContext tlsContext;
* };
* @endcode
* <br>
* -# Implementing @ref TransportRecv_t<br><br>
* @snippet this define_transportrecv
* <br>
* This function is expected to populate a buffer, with bytes received from the
* transport, and return the number of bytes placed in the buffer.
* In the case of TLS over TCP, @ref TransportRecv_t is typically implemented by
* calling the TLS layer function to receive data. In case of plaintext TCP
* without TLS, it is typically implemented by calling the TCP layer receive
* function. @ref TransportRecv_t may be invoked multiple times by the protocol
* library, if fewer bytes than were requested to receive are returned.
* <br><br>
* <b>Example code:</b>
* @code{c}
* int32_t myNetworkRecvImplementation( NetworkContext_t * pNetworkContext,
* void * pBuffer,
* size_t bytesToRecv )
* {
* int32_t bytesReceived = 0;
* bool callTlsRecvFunc = true;
*
* // For a single byte read request, check if data is available on the network.
* if( bytesToRecv == 1 )
* {
* // If no data is available on the network, do not call TLSRecv
* // to avoid blocking for socket timeout.
* if( TLSRecvCount( pNetworkContext->tlsContext ) == 0 )
* {
* callTlsRecvFunc = false;
* }
* }
*
* if( callTlsRecvFunc == true )
* {
* bytesReceived = TLSRecv( pNetworkContext->tlsContext,
* pBuffer,
* bytesToRecv,
* MY_SOCKET_TIMEOUT );
* if( bytesReceived < 0 )
* {
* // If the error code represents a timeout, then the return
* // code should be translated to zero so that the caller
* // can retry the read operation.
* if( bytesReceived == MY_SOCKET_ERROR_TIMEOUT )
* {
* bytesReceived = 0;
* }
* }
* // Handle other cases.
* }
* return bytesReceived;
* }
* @endcode
* <br>
* -# Implementing @ref TransportSend_t<br><br>
* @snippet this define_transportsend
* <br>
* This function is expected to send the bytes, in the given buffer over the
* transport, and return the number of bytes sent.
* In the case of TLS over TCP, @ref TransportSend_t is typically implemented by
* calling the TLS layer function to send data. In case of plaintext TCP
* without TLS, it is typically implemented by calling the TCP layer send
* function. @ref TransportSend_t may be invoked multiple times by the protocol
* library, if fewer bytes than were requested to send are returned.
* <br><br>
* <b>Example code:</b>
* @code{c}
* int32_t myNetworkSendImplementation( NetworkContext_t * pNetworkContext,
* const void * pBuffer,
* size_t bytesToSend )
* {
* int32_t bytesSent = 0;
* bytesSent = TLSSend( pNetworkContext->tlsContext,
* pBuffer,
* bytesToSend,
* MY_SOCKET_TIMEOUT );
*
* // If underlying TCP buffer is full, set the return value to zero
* // so that caller can retry the send operation.
* if( bytesSent == MY_SOCKET_ERROR_BUFFER_FULL )
* {
* bytesSent = 0;
* }
* else if( bytesSent < 0 )
* {
* // Handle socket error.
* }
* // Handle other cases.
*
* return bytesSent;
* }
* @endcode
*/
/**
* @transportstruct
* @typedef NetworkContext_t
* @brief The NetworkContext is an incomplete type. An implementation of this
* interface must define struct NetworkContext for the system requirements.
* This context is passed into the network interface functions.
*/
/* @[define_networkcontext] */
struct NetworkContext;
typedef struct NetworkContext NetworkContext_t;
/* @[define_networkcontext] */
/**
* @transportcallback
* @brief Transport interface for receiving data on the network.
*
* @note It is RECOMMENDED that the transport receive implementation
* does NOT block when requested to read a single byte. A single byte
* read request can be made by the caller to check whether there is a
* new frame available on the network for reading.
* However, the receive implementation MAY block for a timeout period when
* it is requested to read more than 1 byte. This is because once the caller
* is aware that a new frame is available to read on the network, then
* the likelihood of reading more than one byte over the network becomes high.
*
* @param[in] pNetworkContext Implementation-defined network context.
* @param[in] pBuffer Buffer to receive the data into.
* @param[in] bytesToRecv Number of bytes requested from the network.
*
* @return The number of bytes received or a negative value to indicate
* error.
*
* @note If no data is available on the network to read and no error
* has occurred, zero MUST be the return value. A zero return value
* SHOULD represent that the read operation can be retried by calling
* the API function. Zero MUST NOT be returned if a network disconnection
* has occurred.
*/
/* @[define_transportrecv] */
typedef int32_t ( * TransportRecv_t )( NetworkContext_t * pNetworkContext,
void * pBuffer,
size_t bytesToRecv );
/* @[define_transportrecv] */
/**
* @transportcallback
* @brief Transport interface for sending data over the network.
*
* @param[in] pNetworkContext Implementation-defined network context.
* @param[in] pBuffer Buffer containing the bytes to send over the network stack.
* @param[in] bytesToSend Number of bytes to send over the network.
*
* @return The number of bytes sent or a negative value to indicate error.
*
* @note If no data is transmitted over the network due to a full TX buffer and
* no network error has occurred, this MUST return zero as the return value.
* A zero return value SHOULD represent that the send operation can be retried
* by calling the API function. Zero MUST NOT be returned if a network disconnection
* has occurred.
*/
/* @[define_transportsend] */
typedef int32_t ( * TransportSend_t )( NetworkContext_t * pNetworkContext,
const void * pBuffer,
size_t bytesToSend );
/* @[define_transportsend] */
/**
* @brief Transport vector structure for sending multiple messages.
*/
typedef struct TransportOutVector
{
/**
* @brief Base address of data.
*/
const void * iov_base;
/**
* @brief Length of data in buffer.
*/
size_t iov_len;
} TransportOutVector_t;
/**
* @transportcallback
* @brief Transport interface function for "vectored" / scatter-gather based
* writes. This function is expected to iterate over the list of vectors pIoVec
* having ioVecCount entries containing portions of one MQTT message at a maximum.
* If the proper functionality is available, then the data in the list should be
* copied to the underlying TCP buffer before flushing the buffer. Implementing it
* in this fashion will lead to sending of fewer TCP packets for all the values
* in the list.
*
* @note If the proper write functionality is not present for a given device/IP-stack,
* then there is no strict requirement to implement write. Only the send and recv
* interfaces must be defined for the application to work properly.
*
* @param[in] pNetworkContext Implementation-defined network context.
* @param[in] pIoVec An array of TransportIoVector_t structs.
* @param[in] ioVecCount Number of TransportIoVector_t in pIoVec.
*
* @return The number of bytes written or a negative value to indicate error.
*
* @note If no data is written to the buffer due to the buffer being full this MUST
* return zero as the return value.
* A zero return value SHOULD represent that the write operation can be retried
* by calling the API function. Zero MUST NOT be returned if a network disconnection
* has occurred.
*/
/* @[define_transportwritev] */
typedef int32_t ( * TransportWritev_t )( NetworkContext_t * pNetworkContext,
TransportOutVector_t * pIoVec,
size_t ioVecCount );
/* @[define_transportwritev] */
/**
* @transportstruct
* @brief The transport layer interface.
*/
/* @[define_transportinterface] */
typedef struct TransportInterface
{
TransportRecv_t recv; /**< Transport receive function pointer. */
TransportSend_t send; /**< Transport send function pointer. */
TransportWritev_t writev; /**< Transport writev function pointer. */
NetworkContext_t * pNetworkContext; /**< Implementation-defined network context. */
} TransportInterface_t;
/* @[define_transportinterface] */
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* ifndef TRANSPORT_INTERFACE_H_ */

View File

@ -0,0 +1,95 @@
cmake_minimum_required ( VERSION 3.13.0 )
project ( "CoreMQTT 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 if not specified.
if( NOT DEFINED CMAKE_C_STANDARD )
set( CMAKE_C_STANDARD 90 )
endif()
if( NOT DEFINED CMAKE_C_STANDARD_REQUIRED )
set( CMAKE_C_STANDARD_REQUIRED ON )
endif()
# 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 "coreMQTT repository root.")
# Configure options to always show in CMake GUI.
option( BUILD_CLONE_SUBMODULES
"Set this to ON to automatically clone any required Git submodules. When OFF, submodules must be manually cloned."
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}/mqttFilePaths.cmake )
# Target for Coverity analysis that builds the library.
add_library( coverity_analysis
${MQTT_SOURCES}
${MQTT_SERIALIZER_SOURCES} )
# Build MQTT library target without custom config dependency.
target_compile_definitions( coverity_analysis PUBLIC MQTT_DO_NOT_USE_CUSTOM_CONFIG=1 )
target_compile_definitions( coverity_analysis PUBLIC NDEBUG=1 )
# MQTT public include path.
target_include_directories( coverity_analysis PUBLIC ${MQTT_INCLUDE_PUBLIC_DIRS} )
# ==================================== Test Configuration ========================================
# Define a CMock resource path.
set( CMOCK_DIR ${MODULE_ROOT_DIR}/test/unit-test/CMock CACHE INTERNAL "CMock library source directory." )
# Include CMock build configuration.
include( unit-test/cmock_build.cmake )
# Check if the CMock source directory exists, and if not present, clone the submodule
# if BUILD_CLONE_SUBMODULES configuration is enabled.
if( NOT EXISTS ${CMOCK_DIR}/src )
# Attempt to clone CMock.
if( ${BUILD_CLONE_SUBMODULES} )
clone_cmock()
else()
message( FATAL_ERROR "The required submodule CMock does not exist. Either clone it manually, or set BUILD_CLONE_SUBMODULES to 1 to automatically clone it during build." )
endif()
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 CMock and Unit, required for unit testing.
add_cmock_targets()
# Add function to enable CMock based tests and coverage.
include( ${MODULE_ROOT_DIR}/tools/cmock/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} -DCMOCK_DIR=${CMOCK_DIR}
-P ${MODULE_ROOT_DIR}/tools/cmock/coverage.cmake
DEPENDS cmock unity core_mqtt_utest core_mqtt_serializer_utest core_mqtt_state_utest
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)

View File

@ -0,0 +1,24 @@
# Emitted when running CBMC proofs
proofs/**/logs
proofs/**/gotos
proofs/**/report
proofs/**/html
proofs/output
# Emitted by CBMC Viewer
TAGS-*
# Emitted by Arpa
arpa_cmake/
arpa-validation-logs/
Makefile.arpa
# Emitted by litani
.ninja_deps
.ninja_log
.litani_cache_dir
# These files should be overwritten whenever prepare.py runs
cbmc-batch.yaml
__pycache__/

View File

@ -0,0 +1,6 @@
CBMC proof include files
========================
This directory contains include files written for CBMC proof. It is
common to write some code to model aspects of the system under test,
and the header files for this code go here.

View File

@ -0,0 +1,93 @@
/*
* coreMQTT v2.1.1
* 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 core_mqtt_config.h
* @brief This header sets configuration macros for the MQTT library.
*/
#ifndef CORE_MQTT_CONFIG_H_
#define CORE_MQTT_CONFIG_H_
/* Mock a network context for the CBMC proofs. */
struct NetworkContext
{
int NetworkContext;
};
/**
* @brief Determines the maximum number of MQTT PUBLISH messages, pending
* acknowledgement at a time, that are supported for incoming and outgoing
* direction of messages, separately.
*
* QoS 1 and 2 MQTT PUBLISHes require acknowledgement from the server before
* they can be completed. While they are awaiting the acknowledgement, the
* client must maintain information about their state. The value of this
* macro sets the limit on how many simultaneous PUBLISH states an MQTT
* context maintains, separately, for both incoming and outgoing direction of
* PUBLISHes.
*
* @note This definition must exist in order to compile. 10U is a typical value
* used in the MQTT demos.
*/
#define MQTT_STATE_ARRAY_MAX_COUNT ( 10U )
/**
* @brief Retry count for reading CONNACK from network.
*
* The MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT will be used only when the
* timeoutMs parameter of #MQTT_Connect() is passed as 0 . The transport
* receive for CONNACK will be retried MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT
* times before timing out. A value of 0 for this config will cause the
* transport receive for CONNACK to be invoked only once.
*/
#define MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT ( 2U )
/**
* @brief Number of milliseconds to wait for a ping response to a ping
* request as part of the keep-alive mechanism.
*
* If a ping response is not received before this timeout, then
* #MQTT_ProcessLoop will return #MQTTKeepAliveTimeout.
*/
#define MQTT_PINGRESP_TIMEOUT_MS ( 5000U )
/**
* @brief The maximum duration of receiving no data over network when
* attempting to read an incoming MQTT packet by the #MQTT_ProcessLoop or
* #MQTT_ReceiveLoop API functions.
*
* When an incoming MQTT packet is detected, the transport receive function
* may be called multiple times until all the expected number of bytes for the
* packet are received. This timeout represents the maximum duration of polling
* for any data to be received over the network for the incoming.
* If the timeout expires, the #MQTT_ProcessLoop or #MQTT_ReceiveLoop functions
* return #MQTTRecvFailed.
*
* This is set to 1 to exit right away after a zero is received in the transport
* receive stub. There is no added value, in proving memory safety, to repeat
* the logic that checks if the polling timeout is reached.
*/
#define MQTT_RECV_POLLING_TIMEOUT_MS ( 1U )
#endif /* ifndef CORE_MQTT_CONFIG_H_ */

View File

@ -0,0 +1,47 @@
/*
* coreMQTT v2.1.1
* 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 event_callback_stub.h
* @brief Stub definition for the application defined MQTT library incoming
* event callback.
*/
#ifndef EVENT_CALLBACK_STUB_H_
#define EVENT_CALLBACK_STUB_H_
/* mqtt.h must precede including this header. */
/**
* @brief User defined callback for receiving incoming publishes and incoming
* acks.
*
* @param[in] pContext Initialized MQTT context.
* @param[in] pPacketInfo Information on the type of incoming MQTT packet.
* @param[in] pDeserializedInfo Deserialized information from incoming packet.
*/
void EventCallbackStub( MQTTContext_t * pContext,
MQTTPacketInfo_t * pPacketInfo,
MQTTDeserializedInfo_t * pDeserializedInfo );
#endif /* ifndef EVENT_CALLBACK_STUB_H_ */

View File

@ -0,0 +1,40 @@
/*
* coreMQTT v2.1.1
* 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 get_time_stub.h
* @brief Stub definition for the application defined callback to retrieve the
* current time in milliseconds.
*/
#ifndef GET_TIME_STUB_H_
#define GET_TIME_STUB_H_
/**
* Application defined callback to retrieve the current time in milliseconds.
*
* @return The current time in milliseconds.
*/
uint32_t GetCurrentTimeStub( void );
#endif /* ifndef GET_TIME_STUB_H_ */

View File

@ -0,0 +1,168 @@
/*
* coreMQTT v2.1.1
* 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 mqtt_cbmc_state.h
* @brief Allocation and assumption utilities for the MQTT library CBMC proofs.
*/
#ifndef MQTT_CBMC_STATE_H_
#define MQTT_CBMC_STATE_H_
#include <stdbool.h>
/* mqtt.h must precede including this header. */
#define IMPLIES( a, b ) ( !( a ) || ( b ) )
/**
* @brief Allocate a #MQTTPacketInfo_t object.
*
* @param[in] pPacketInfo #MQTTPacketInfo_t object information.
*
* @return NULL or allocated #MQTTPacketInfo_t memory.
*/
MQTTPacketInfo_t * allocateMqttPacketInfo( MQTTPacketInfo_t * pPacketInfo );
/**
* @brief Validate a #MQTTPacketInfo_t object.
*
* @param[in] pPacketInfo #MQTTPacketInfo_t object to validate.
*
* @return True if the #MQTTPacketInfo_t object is valid, false otherwise.
*
* @note A NULL object is a valid object. This is for coverage of the NULL
* parameter checks in the function under proof.
*/
bool isValidMqttPacketInfo( const MQTTPacketInfo_t * pPacketInfo );
/**
* @brief Allocate a #MQTTPublishInfo_t object.
*
* @param[in] pPublishInfo #MQTTPublishInfo_t object information.
*
* @return NULL or allocated #MQTTPublishInfo_t memory.
*/
MQTTPublishInfo_t * allocateMqttPublishInfo( MQTTPublishInfo_t * pPublishInfo );
/**
* @brief Validate a #MQTTPublishInfo_t object.
*
* @param[in] pPublishInfo #MQTTPublishInfo_t object to validate.
*
* @return True if the #MQTTPublishInfo_t object is valid, false otherwise.
*
* @note A NULL object is a valid object. This is for coverage of the NULL
* parameter checks in the function under proof.
*/
bool isValidMqttPublishInfo( const MQTTPublishInfo_t * pPublishInfo );
/**
* @brief Allocate a #MQTTConnectInfo_t object.
*
* @param[in] pConnectInfo #MQTTConnectInfo_t object information.
*
* @return NULL or allocated #MQTTConnectInfo_t memory.
*/
MQTTConnectInfo_t * allocateMqttConnectInfo( MQTTConnectInfo_t * pConnectInfo );
/**
* @brief Validate a #MQTTConnectInfo_t object.
*
* @param[in] pConnectInfo #MQTTConnectInfo_t object to validate.
*
* @return True if the #MQTTConnectInfo_t object is valid, false otherwise.
*
* @note A NULL object is a valid object. This is for coverage of the NULL
* parameter checks in the function under proof.
*/
bool isValidMqttConnectInfo( const MQTTConnectInfo_t * pConnectInfo );
/**
* @brief Allocate a #MQTTFixedBuffer_t object.
*
* @param[in] pBuffer #MQTTFixedBuffer_t object information.
*
* @return NULL or allocated #MQTTFixedBuffer_t memory.
*/
MQTTFixedBuffer_t * allocateMqttFixedBuffer( MQTTFixedBuffer_t * pFixedBuffer );
/**
* @brief Validate a #MQTTFixedBuffer_t object.
*
* @param[in] pBuffer #MQTTFixedBuffer_t object to validate.
*
* @return True if the #MQTTFixedBuffer_t object is valid, false otherwise.
*
* @note A NULL object is a valid object. This is for coverage of the NULL
* parameter checks in the function under proof.
*/
bool isValidMqttFixedBuffer( const MQTTFixedBuffer_t * pFixedBuffer );
/**
* @brief Allocate an array of #MQTTSubscribeInfo_t objects.
*
* @param[in] pSubscriptionList #MQTTSubscribeInfo_t object information.
* @param[in] subscriptionCount The amount of #MQTTSubscribeInfo_t objects to allocate.
*
* @return NULL or allocated #MQTTSubscribeInfo_t array.
*/
MQTTSubscribeInfo_t * allocateMqttSubscriptionList( MQTTSubscribeInfo_t * pSubscriptionList,
size_t subscriptionCount );
/**
* @brief Validate an array of #MQTTSubscribeInfo_t objects.
*
* @param[in] pSubscriptionList #MQTTSubscribeInfo_t object information.
* @param[in] subscriptionCount The length of #MQTTSubscribeInfo_t objects in the pSubscriptionList.
*
* @return True if the #MQTTSubscribeInfo_t is valid.
*
* @note A NULL object is a valid object. This is for coverage of the NULL
* parameter checks in the function under proof.
*/
bool isValidMqttSubscriptionList( MQTTSubscribeInfo_t * pSubscriptionList,
size_t subscriptionCount );
/**
* @brief Allocate a #MQTTContext_t object.
*
* @param[in] pBuffer #MQTTContext_t object information.
*
* @return NULL or allocated #MQTTContext_t memory.
*/
MQTTContext_t * allocateMqttContext( MQTTContext_t * pContext );
/**
* @brief Validate a #MQTTContext_t object.
*
* @param[in] pBuffer #MQTTContext_t object to validate.
*
* @return True if the #MQTTContext_t object is valid, false otherwise.
*
* @note A NULL object is a valid object. This is for coverage of the NULL
* parameter checks in the function under proof.
*/
bool isValidMqttContext( const MQTTContext_t * pContext );
#endif /* ifndef MQTT_CBMC_STATE_H_ */

View File

@ -0,0 +1,61 @@
/*
* coreMQTT v2.1.1
* 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 network_interface_stubs.h
* @brief Stub definitions for the application defined transport interface send
* and receive callback.
*/
#ifndef NETWORK_INTERFACE_STUBS_H_
#define NETWORK_INTERFACE_STUBS_H_
/* transport_interface.h must precede including this header. */
/**
* @brief Application defined network interface receive function.
*
* @param[in] pNetworkContext Application defined network interface context.
* @param[out] pBuffer MQTT network receive buffer.
* @param[in] bytesToRecv MQTT requested bytes.
*
* @return Any value from INT32_MIN to INT32_MAX.
*/
int32_t NetworkInterfaceReceiveStub( NetworkContext_t * pNetworkContext,
void * pBuffer,
size_t bytesToRecv );
/**
* @brief Application defined network interface send function.
*
* @param[in] pNetworkContext Application defined network interface context.
* @param[out] pBuffer MQTT network send buffer.
* @param[in] bytesToSend Number of bytes to send over the network.
*
* @return Any value from INT32_MIN to INT32_MAX.
*/
int32_t NetworkInterfaceSendStub( NetworkContext_t * pNetworkContext,
const void * pBuffer,
size_t bytesToSend );
#endif /* ifndef NETWORK_INTERFACE_STUBS_H_ */

View File

@ -0,0 +1,157 @@
/*
* coreMQTT v2.1.1
* 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 MQTT_Connect_harness.c
* @brief Implements the proof harness for MQTT_Connect function.
*/
#include "core_mqtt.h"
#include "mqtt_cbmc_state.h"
/**
* @brief Implement a get time function to return timeout after certain
* iterations have been made in the code. This ensures that we do not hit
* unwinding error in CBMC. In real life scenarios, the send function will
* not just keep accepting 1 byte at a time for a long time since it just
* gets added to the TCP buffer.
*
* @return The global system time.
*/
static uint32_t ulGetTimeFunction( void )
{
static uint32_t systemTime = 0;
if( systemTime >= MAX_NETWORK_SEND_TRIES )
{
systemTime = systemTime + MQTT_SEND_TIMEOUT_MS + 1;
}
else
{
systemTime = systemTime + 1;
}
return systemTime;
}
void harness()
{
MQTTContext_t * pContext;
MQTTConnectInfo_t * pConnectInfo;
MQTTPublishInfo_t * pWillInfo;
uint32_t timeoutMs;
size_t totalMessageLength = 0U;
bool * pSessionPresent;
pContext = allocateMqttContext( NULL );
__CPROVER_assume( isValidMqttContext( pContext ) );
__CPROVER_assume( pContext != NULL );
__CPROVER_assume( pContext->networkBuffer.pBuffer != NULL );
pContext->getTime = ulGetTimeFunction;
pConnectInfo = allocateMqttConnectInfo( NULL );
__CPROVER_assume( isValidMqttConnectInfo( pConnectInfo ) );
if( pConnectInfo != NULL )
{
/* 128^4 is the length imposed by the MQTT spec. */
__CPROVER_assume( pConnectInfo->passwordLength < 268435456 );
__CPROVER_assume( pConnectInfo->userNameLength < 268435456 );
__CPROVER_assume( pConnectInfo->clientIdentifierLength < 268435456 );
totalMessageLength += pConnectInfo->passwordLength;
totalMessageLength += pConnectInfo->userNameLength;
totalMessageLength += pConnectInfo->clientIdentifierLength;
if( pConnectInfo->passwordLength == 0 )
{
pConnectInfo->pPassword = NULL;
}
else
{
__CPROVER_assume( pConnectInfo->pPassword != NULL );
}
if( pConnectInfo->userNameLength == 0 )
{
pConnectInfo->pUserName = NULL;
}
else
{
__CPROVER_assume( pConnectInfo->pUserName != NULL );
}
if( pConnectInfo->clientIdentifierLength == 0 )
{
pConnectInfo->pClientIdentifier = NULL;
}
else
{
__CPROVER_assume( pConnectInfo->pClientIdentifier != NULL );
}
}
pWillInfo = allocateMqttPublishInfo( NULL );
__CPROVER_assume( isValidMqttPublishInfo( pWillInfo ) );
if( pWillInfo != NULL )
{
/* 128^4 is the length imposed by the MQTT spec. */
__CPROVER_assume( pWillInfo->topicNameLength < 268435456 );
__CPROVER_assume( pWillInfo->payloadLength < 268435456 );
if( pWillInfo->topicNameLength == 0 )
{
pWillInfo->pTopicName = NULL;
}
else
{
__CPROVER_assume( pWillInfo->pTopicName != NULL );
}
if( pWillInfo->payloadLength == 0 )
{
pWillInfo->pPayload = NULL;
}
else
{
__CPROVER_assume( pWillInfo->pPayload != NULL );
}
totalMessageLength += pWillInfo->topicNameLength;
totalMessageLength += pWillInfo->payloadLength;
}
/* 128^4 is the length imposed by the MQTT spec. */
__CPROVER_assume( totalMessageLength <= 268435456 );
pSessionPresent = malloc( sizeof( bool ) );
/* The MQTT_RECEIVE_TIMEOUT is used here to control the number of loops
* when receiving on the network. The default is used here because memory
* safety can be proven in only a few iterations. */
__CPROVER_assume( timeoutMs < MQTT_RECEIVE_TIMEOUT );
MQTT_Connect( pContext, pConnectInfo, pWillInfo, timeoutMs, pSessionPresent );
}

View File

@ -0,0 +1,96 @@
#
# 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.
#
HARNESS_ENTRY=harness
HARNESS_FILE=MQTT_Connect_harness
PROOF_UID=MQTT_Connect
# Please see test/cbmc/stubs/network_interface_subs.c for
# more information on MAX_NETWORK_SEND_TRIES.
MAX_NETWORK_SEND_TRIES=3
# Bound on the timeout in receiveConnack. This timeout is bounded because
# memory saftey can be proven in a only a few iteration of the MQTT operations.
# Each iteration will try to receive a single packet in its entirety. With a
# time out of 3 we can get coverage of the entire function. Another iteration
# performed will unnecessarily duplicate the proof.
MQTT_RECEIVE_TIMEOUT=3
# The NetworkInterfaceReceiveStub is called once for getting the incoming packet
# type with one byte of data, then it is called multiple times to reveive the
# packet.
MAX_NETWORK_RECV_TRIES=4
# Please see test/cbmc/include/core_mqtt_config.h for more
# information on these defines.
MQTT_STATE_ARRAY_MAX_COUNT=11
MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT=3
CONNECT_PACKET_VECTORS = 12
DEFINES += -DMQTT_RECEIVE_TIMEOUT=$(MQTT_RECEIVE_TIMEOUT)
DEFINES += -DMAX_NETWORK_SEND_TRIES=$(MAX_NETWORK_SEND_TRIES)
DEFINES += -DMAX_NETWORK_RECV_TRIES=$(MAX_NETWORK_RECV_TRIES)
INCLUDES +=
# These functions do not coincide with the call graph of MQTT_Connect, but are
# found by CBMC during processing in logs/MQTT_Connect_harness3.txt. We remove
# the function bodies to improve coverage accuracy.
REMOVE_FUNCTION_BODY += MQTT_ProcessLoop
REMOVE_FUNCTION_BODY += MQTT_ReceiveLoop
REMOVE_FUNCTION_BODY += __CPROVER_file_local_core_mqtt_c_handleIncomingPublish
REMOVE_FUNCTION_BODY += __CPROVER_file_local_core_mqtt_c_handleKeepAlive
#REMOVE_FUNCTION_BODY += __CPROVER_file_local_core_mqtt_c_sendMessageVector
#REMOVE_FUNCTION_BODY += __CPROVER_file_local_core_mqtt_c_sendBuffer
# The loop below is unwound once more than the timeout. The loop below uses
# the user passed in timeout to break the loop.
UNWINDSET += __CPROVER_file_local_core_mqtt_c_discardPacket.0:$(MQTT_RECEIVE_TIMEOUT)
UNWINDSET += __CPROVER_file_local_core_mqtt_c_recvExact.0:$(MAX_NETWORK_RECV_TRIES)
# If the user passed in timeout is zero, then the loop will run until the
# MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT is reached.
UNWINDSET += __CPROVER_file_local_core_mqtt_c_receiveConnack.0:$(MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT)
# Unlike recvExact, sendBuffer is not bounded by the timeout. The loop in
# sendBuffer will continue until all the bytes are sent or a network error
# occurs. Please see NetworkInterfaceReceiveStub in
# libraries\standard\mqtt\cbmc\stubs\network_interface_stubs.c for more
# information.
UNWINDSET += __CPROVER_file_local_core_mqtt_c_sendBuffer.0:$(MAX_NETWORK_SEND_TRIES)
# The loops are unwound 5 times because these functions divides a size_t
# variable by 128 until it reaches zero to stop the loop.
# log128(SIZE_MAX) = 4.571...
UNWINDSET += __CPROVER_file_local_core_mqtt_serializer_c_encodeRemainingLength.0:5
UNWINDSET += __CPROVER_file_local_core_mqtt_serializer_c_getRemainingLength.0:5
# This loop will run for the maximum number of publishes pending
# acknowledgements plus one. This value is set in
# test/cbmc/include/core_mqtt_config.h.
UNWINDSET += __CPROVER_file_local_core_mqtt_state_c_stateSelect.0:$(MQTT_STATE_ARRAY_MAX_COUNT)
UNWINDSET += __CPROVER_file_local_core_mqtt_c_sendMessageVector.0:${CONNECT_PACKET_VECTORS}
UNWINDSET += __CPROVER_file_local_core_mqtt_c_sendMessageVector.1:${CONNECT_PACKET_VECTORS}
UNWINDSET += __CPROVER_file_local_core_mqtt_c_sendMessageVector.2:${CONNECT_PACKET_VECTORS}
PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/sources/mqtt_cbmc_state.c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/stubs/network_interface_stubs.c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/stubs/get_time_stub.c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/stubs/event_callback_stub.c
PROJECT_SOURCES += $(SRCDIR)/source/core_mqtt.c
PROJECT_SOURCES += $(SRCDIR)/source/core_mqtt_serializer.c
PROJECT_SOURCES += $(SRCDIR)/source/core_mqtt_state.c
EXPENSIVE = true
include ../Makefile.common

View File

@ -0,0 +1,10 @@
MQTT_Connect proof
==============
This directory contains a memory safety proof for MQTT_Connect.
To run the proof.
* Add cbmc, goto-cc, goto-instrument, goto-analyzer, and cbmc-viewer
to your path.
* Run "make".
* Open html/index.html in a web browser.

View File

@ -0,0 +1 @@
# This file marks this directory as containing a CBMC proof.

View File

@ -0,0 +1,7 @@
{ "expected-missing-functions":
[
],
"proof-name": "MQTT_Connect",
"proof-root": "test/cbmc/proofs"
}

View File

@ -0,0 +1,48 @@
/*
* coreMQTT v2.1.1
* 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 MQTT_DeserializeAck_harness.c
* @brief Implements the proof harness for MQTT_DeserializeAck function.
*/
#include "core_mqtt.h"
#include "mqtt_cbmc_state.h"
void harness()
{
MQTTPacketInfo_t * pIncomingPacket;
uint16_t * pPacketId;
bool * pSessionPresent;
pIncomingPacket = allocateMqttPacketInfo( NULL );
__CPROVER_assume( isValidMqttPacketInfo( pIncomingPacket ) );
/* These are allocated for coverage of a NULL input. */
pPacketId = malloc( sizeof( uint16_t ) );
pSessionPresent = malloc( sizeof( bool ) );
MQTT_DeserializeAck( pIncomingPacket,
pPacketId,
pSessionPresent );
}

View File

@ -0,0 +1,40 @@
#
# 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.
#
HARNESS_ENTRY=harness
HARNESS_FILE=MQTT_DeserializeAck_harness
PROOF_UID=MQTT_DeserializeAck
# The maximum remaining length is bounded for MQTT_DeserializeAck() in order to
# place a limit on the number of iterations in deserializing a SUBACK. Please
# see REMAINING_LENGTH_MAX in libraries\standard\mqtt\cbmc\sources\mqtt_cbmc_state.c.
REMAINING_LENGTH_MAX=5
DEFINES += -DREMAINING_LENGTH_MAX=$(REMAINING_LENGTH_MAX)
INCLUDES +=
REMOVE_FUNCTION_BODY +=
UNWINDSET += __CPROVER_file_local_core_mqtt_serializer_c_readSubackStatus.0:$(REMAINING_LENGTH_MAX)
PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/sources/mqtt_cbmc_state.c
PROJECT_SOURCES += $(SRCDIR)/source/core_mqtt_serializer.c
include ../Makefile.common

View File

@ -0,0 +1,10 @@
MQTT_DeserializeAck proof
==============
This directory contains a memory safety proof for MQTT_DeserializeAck.
To run the proof.
* Add cbmc, goto-cc, goto-instrument, goto-analyzer, and cbmc-viewer
to your path.
* Run "make".
* Open html/index.html in a web browser.

View File

@ -0,0 +1 @@
# This file marks this directory as containing a CBMC proof.

View File

@ -0,0 +1,7 @@
{ "expected-missing-functions":
[
],
"proof-name": "MQTT_DeserializeAck",
"proof-root": "test/cbmc/proofs"
}

View File

@ -0,0 +1,50 @@
/*
* coreMQTT v2.1.1
* 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 MQTT_DeserializePublish_harness.c
* @brief Implements the proof harness for MQTT_DeserializePublish function.
*/
#include "core_mqtt.h"
#include "mqtt_cbmc_state.h"
void harness()
{
MQTTPacketInfo_t * pIncomingPacket;
MQTTPublishInfo_t * pPublishInfo;
uint16_t * pPacketId;
pIncomingPacket = allocateMqttPacketInfo( NULL );
__CPROVER_assume( isValidMqttPacketInfo( pIncomingPacket ) );
pPublishInfo = allocateMqttPublishInfo( NULL );
__CPROVER_assume( isValidMqttPublishInfo( pPublishInfo ) );
pPacketId = malloc( sizeof( uint16_t ) );
/* This function grabs the topic name, the topic name length, the
* the payload, and the payload length. */
MQTT_DeserializePublish( pIncomingPacket, pPacketId, pPublishInfo );
}

View File

@ -0,0 +1,36 @@
#
# 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.
#
HARNESS_ENTRY=harness
HARNESS_FILE=MQTT_DeserializePublish_harness
PROOF_UID=MQTT_DeserializePublish
DEFINES +=
INCLUDES +=
REMOVE_FUNCTION_BODY +=
UNWINDSET +=
PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/sources/mqtt_cbmc_state.c
PROJECT_SOURCES += $(SRCDIR)/source/core_mqtt_serializer.c
include ../Makefile.common

View File

@ -0,0 +1,10 @@
MQTT_DeserializePublish proof
==============
This directory contains a memory safety proof for MQTT_DeserializePublish.
To run the proof.
* Add cbmc, goto-cc, goto-instrument, goto-analyzer, and cbmc-viewer
to your path.
* Run "make".
* Open html/index.html in a web browser.

View File

@ -0,0 +1 @@
# This file marks this directory as containing a CBMC proof.

View File

@ -0,0 +1,7 @@
{ "expected-missing-functions":
[
],
"proof-name": "MQTT_DeserializePublish",
"proof-root": "test/cbmc"
}

View File

@ -0,0 +1,42 @@
/*
* coreMQTT v2.1.1
* 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 MQTT_Disconnect_harness.c
* @brief Implements the proof harness for MQTT_Disconnect function.
*/
#include "core_mqtt.h"
#include "mqtt_cbmc_state.h"
void harness()
{
MQTTContext_t * pContext;
pContext = allocateMqttContext( NULL );
__CPROVER_assume( isValidMqttContext( pContext ) );
__CPROVER_assume( pContext != NULL );
__CPROVER_assume( pContext->networkBuffer.pBuffer != NULL );
MQTT_Disconnect( pContext );
}

View File

@ -0,0 +1,49 @@
#
# 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.
#
HARNESS_ENTRY=harness
HARNESS_FILE=MQTT_Disconnect_harness
PROOF_UID=MQTT_Disconnect
# Please see test/cbmc/stubs/network_interface_subs.c for
# more information on MAX_NETWORK_SEND_TRIES.
MAX_NETWORK_SEND_TRIES=3
DEFINES += -DMAX_NETWORK_SEND_TRIES=$(MAX_NETWORK_SEND_TRIES)
INCLUDES +=
REMOVE_FUNCTION_BODY +=
# Unlike recvExact, sendBuffer is not bounded by the timeout. The loop in
# sendBuffer will continue until all the bytes are sent or a network error
# occurs. Please see NetworkInterfaceReceiveStub in
# libraries\standard\mqtt\cbmc\stubs\network_interface_stubs.c for more
# information.
UNWINDSET += __CPROVER_file_local_core_mqtt_c_sendBuffer.0:$(MAX_NETWORK_SEND_TRIES)
PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/sources/mqtt_cbmc_state.c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/stubs/network_interface_stubs.c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/stubs/get_time_stub.c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/stubs/event_callback_stub.c
PROJECT_SOURCES += $(SRCDIR)/source/core_mqtt.c
PROJECT_SOURCES += $(SRCDIR)/source/core_mqtt_serializer.c
PROJECT_SOURCES += $(SRCDIR)/source/core_mqtt_state.c
include ../Makefile.common

View File

@ -0,0 +1,10 @@
MQTT_Disconnect proof
==============
This directory contains a memory safety proof for MQTT_Disconnect.
To run the proof.
* Add cbmc, goto-cc, goto-instrument, goto-analyzer, and cbmc-viewer
to your path.
* Run "make".
* Open html/index.html in a web browser.

View File

@ -0,0 +1 @@
# This file marks this directory as containing a CBMC proof.

View File

@ -0,0 +1,7 @@
{ "expected-missing-functions":
[
],
"proof-name": "MQTT_Disconnect",
"proof-root": "test/cbmc/proofs"
}

View File

@ -0,0 +1,50 @@
/*
* coreMQTT v2.1.1
* 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 MQTT_GetIncomingPacketTypeAndLength_harness.c
* @brief Implements the proof harness for MQTT_GetIncomingPacketTypeAndLength function.
*/
#include "core_mqtt.h"
#include "network_interface_stubs.h"
#include "mqtt_cbmc_state.h"
void harness()
{
/* NetworkContext_t is an application defined network interface context. It
* is passed through to the readFunc parameter of
* MQTT_GetIncomingPacketTypeAndLength(). */
NetworkContext_t networkContext;
/* MQTT_GetIncomingPacketTypeAndLength() will set only the remainingLength
* field in the input MQTTPacketInfo_t structure. */
MQTTPacketInfo_t * pIncomingPacket;
pIncomingPacket = allocateMqttPacketInfo( NULL );
__CPROVER_assume( isValidMqttPacketInfo( pIncomingPacket ) );
MQTT_GetIncomingPacketTypeAndLength( NetworkInterfaceReceiveStub,
&networkContext,
pIncomingPacket );
}

View File

@ -0,0 +1,40 @@
#
# 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.
#
HARNESS_ENTRY=harness
HARNESS_FILE=MQTT_GetIncomingPacketTypeAndLength_harness
PROOF_UID=MQTT_GetIncomingPacketTypeAndLength
DEFINES +=
INCLUDES +=
REMOVE_FUNCTION_BODY +=
# The getRemainingLength loop is unwound 5 times because getRemainingLength()
# divides a size_t variable by 128 until it reaches zero to stop the loop.
# log128(SIZE_MAX) = 4.571...
UNWINDSET += __CPROVER_file_local_core_mqtt_serializer_c_getRemainingLength.0:5
PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/sources/mqtt_cbmc_state.c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/stubs/network_interface_stubs.c
PROJECT_SOURCES += $(SRCDIR)/source/core_mqtt_serializer.c
include ../Makefile.common

View File

@ -0,0 +1,10 @@
MQTT_GetIncomingPacketTypeAndLength proof
==============
This directory contains a memory safety proof for MQTT_GetIncomingPacketTypeAndLength.
To run the proof.
* Add cbmc, goto-cc, goto-instrument, goto-analyzer, and cbmc-viewer
to your path.
* Run "make".
* Open html/index.html in a web browser.

View File

@ -0,0 +1 @@
# This file marks this directory as containing a CBMC proof.

View File

@ -0,0 +1,7 @@
{ "expected-missing-functions":
[
],
"proof-name": "MQTT_GetIncomingPacketTypeAndLength",
"proof-root": "test/cbmc/proofs"
}

View File

@ -0,0 +1,42 @@
/*
* coreMQTT v2.1.1
* 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 MQTT_GetPacketId_harness.c
* @brief Implements the proof harness for MQTT_GetPacketId function.
*/
#include "core_mqtt.h"
#include "mqtt_cbmc_state.h"
void harness()
{
/* The MQTTContext_t is allocated such that we can test a NULL input.
* MQTT_GetPacketId() touches only the nextPacketId field in MQTTContext_t.
* This nextPacketId is left unbounded to verify the function under harness.
*/
MQTTContext_t * pContext = malloc( sizeof( MQTTContext_t ) );
MQTT_GetPacketId( pContext );
}

View File

@ -0,0 +1,36 @@
#
# 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.
#
HARNESS_ENTRY=harness
HARNESS_FILE=MQTT_GetPacketId_harness
PROOF_UID=MQTT_GetPacketId
DEFINES +=
INCLUDES +=
REMOVE_FUNCTION_BODY +=
UNWINDSET +=
PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/sources/mqtt_cbmc_state.c
PROJECT_SOURCES += $(SRCDIR)/source/core_mqtt.c
include ../Makefile.common

View File

@ -0,0 +1,10 @@
MQTT_GetPacketId proof
==============
This directory contains a memory safety proof for MQTT_GetPacketId.
To run the proof.
* Add cbmc, goto-cc, goto-instrument, goto-analyzer, and cbmc-viewer
to your path.
* Run "make".
* Open html/index.html in a web browser.

View File

@ -0,0 +1 @@
# This file marks this directory as containing a CBMC proof.

View File

@ -0,0 +1,7 @@
{ "expected-missing-functions":
[
],
"proof-name": "MQTT_GetPacketId",
"proof-root": "test/cbmc/proofs"
}

View File

@ -0,0 +1,50 @@
/*
* coreMQTT v2.1.1
* 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 MQTT_GetSubAckStatusCodes_harness.c
* @brief Implements the proof harness for MQTT_GetSubAckStatusCodes function.
*/
#include "core_mqtt.h"
#include "mqtt_cbmc_state.h"
void harness()
{
MQTTPacketInfo_t * pSubackPacket;
uint8_t ** pPayloadStart;
size_t * pPayloadSize;
pSubackPacket = allocateMqttPacketInfo( NULL );
__CPROVER_assume( isValidMqttPacketInfo( pSubackPacket ) );
/* pPayloadStart and pPayloadSize are output parameters, and
* thus, don't carry any assumptions. */
pPayloadStart = malloc( sizeof( uint8_t * ) );
pPayloadSize = malloc( sizeof( size_t ) );
MQTT_GetSubAckStatusCodes( pSubackPacket,
pPayloadStart,
pPayloadSize );
}

View File

@ -0,0 +1,36 @@
#
# 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.
#
HARNESS_ENTRY=harness
HARNESS_FILE=MQTT_GetSubAckStatusCodes_harness
PROOF_UID=MQTT_GetSubAckStatusCodes
DEFINES +=
INCLUDES +=
REMOVE_FUNCTION_BODY +=
UNWINDSET +=
PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/sources/mqtt_cbmc_state.c
PROJECT_SOURCES += $(SRCDIR)/source/core_mqtt.c
include ../Makefile.common

View File

@ -0,0 +1,10 @@
MQTT_GetSubAckStatusCodes proof
==============
This directory contains a memory safety proof for MQTT_GetSubAckStatusCodes.
To run the proof.
* Add cbmc, goto-cc, goto-instrument, goto-analyzer, and cbmc-viewer
to your path.
* Run "make".
* Open html/index.html in a web browser.

View File

@ -0,0 +1 @@
# This file marks this directory as containing a CBMC proof.

View File

@ -0,0 +1,7 @@
{ "expected-missing-functions":
[
],
"proof-name": "MQTT_GetSubAckStatusCodes",
"proof-root": "../../../../.."
}

View File

@ -0,0 +1,52 @@
/*
* coreMQTT v2.1.1
* 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 MQTT_Init_harness.c
* @brief Implements the proof harness for MQTT_Init function.
*/
#include "core_mqtt.h"
#include "mqtt_cbmc_state.h"
void harness()
{
MQTTContext_t * pContext;
TransportInterface_t * pTransportInterface;
MQTTGetCurrentTimeFunc_t getTimeFunction;
MQTTEventCallback_t userCallback;
MQTTFixedBuffer_t * pNetworkBuffer;
pContext = malloc( sizeof( MQTTContext_t ) );
pTransportInterface = malloc( sizeof( TransportInterface_t ) );
getTimeFunction = malloc( sizeof( MQTTGetCurrentTimeFunc_t ) );
userCallback = malloc( sizeof( MQTTEventCallback_t ) );
pNetworkBuffer = malloc( sizeof( MQTTFixedBuffer_t ) );
MQTT_Init( pContext,
pTransportInterface,
getTimeFunction,
userCallback,
pNetworkBuffer );
}

View File

@ -0,0 +1,36 @@
#
# 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.
#
HARNESS_ENTRY=harness
HARNESS_FILE=MQTT_Init_harness
PROOF_UID=MQTT_Init
DEFINES +=
INCLUDES +=
REMOVE_FUNCTION_BODY +=
UNWINDSET +=
PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/sources/mqtt_cbmc_state.c
PROJECT_SOURCES += $(SRCDIR)/source/core_mqtt.c
include ../Makefile.common

View File

@ -0,0 +1,10 @@
MQTT_Init proof
==============
This directory contains a memory safety proof for MQTT_Init.
To run the proof.
* Add cbmc, goto-cc, goto-instrument, goto-analyzer, and cbmc-viewer
to your path.
* Run "make".
* Open html/index.html in a web browser.

View File

@ -0,0 +1 @@
# This file marks this directory as containing a CBMC proof.

View File

@ -0,0 +1,7 @@
{ "expected-missing-functions":
[
],
"proof-name": "MQTT_Init",
"proof-root": "test/cbmc/proofs"
}

View File

@ -0,0 +1,52 @@
/*
* coreMQTT v2.1.1
* 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 MQTT_MatchTopic_harness.c
* @brief Implements the proof harness for MQTT_MatchTopic function.
*/
#include "core_mqtt.h"
#include "mqtt_cbmc_state.h"
void harness()
{
const char * pTopicName;
uint16_t nameLength;
const char * pTopicFilter;
uint16_t filterLength;
bool * pMatchResult;
__CPROVER_assume( nameLength < MAX_TOPIC_NAME_FILTER_LENGTH );
pTopicName = malloc( ( sizeof( char ) * nameLength ) );
__CPROVER_assume( filterLength < MAX_TOPIC_NAME_FILTER_LENGTH );
pTopicFilter = malloc( ( sizeof( char ) * filterLength ) );
pMatchResult = malloc( sizeof( bool ) );
MQTT_MatchTopic( pTopicName,
nameLength,
pTopicFilter,
filterLength,
pMatchResult );
}

View File

@ -0,0 +1,43 @@
#
# 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.
#
HARNESS_ENTRY=harness
HARNESS_FILE=MQTT_MatchTopic_harness
PROOF_UID=MQTT_MatchTopic
# The topic name/filter length are bounded, so that the loops in topic matching algorithmic
# functions called by MQTT_MatchTopic can be unwound to an expected
# amount that won't make the proof run too long.
MAX_TOPIC_NAME_FILTER_LENGTH=10
DEFINES += -DMAX_TOPIC_NAME_FILTER_LENGTH=$(MAX_TOPIC_NAME_FILTER_LENGTH)
INCLUDES +=
REMOVE_FUNCTION_BODY +=
UNWINDSET += __CPROVER_file_local_core_mqtt_c_matchTopicFilter.0:$(MAX_TOPIC_NAME_FILTER_LENGTH)
UNWINDSET += strncmp.0:$(MAX_TOPIC_NAME_FILTER_LENGTH)
UNWINDSET += __CPROVER_file_local_core_mqtt_c_matchWildcards.0:$(MAX_TOPIC_NAME_FILTER_LENGTH)
PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/sources/mqtt_cbmc_state.c
PROJECT_SOURCES += $(SRCDIR)/source/core_mqtt.c
include ../Makefile.common

View File

@ -0,0 +1 @@
# This file marks this directory as containing a CBMC proof.

View File

@ -0,0 +1,7 @@
{ "expected-missing-functions":
[
],
"proof-name": "MQTT_MatchTopic",
"proof-root": "standard/mqtt/cbmc/proofs"
}

View File

@ -0,0 +1,40 @@
/*
* coreMQTT v2.1.1
* 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 MQTT_Ping_harness.c
* @brief Implements the proof harness for MQTT_Ping function.
*/
#include "core_mqtt.h"
#include "mqtt_cbmc_state.h"
void harness()
{
MQTTContext_t * pContext;
pContext = allocateMqttContext( NULL );
__CPROVER_assume( isValidMqttContext( pContext ) );
MQTT_Ping( pContext );
}

View File

@ -0,0 +1,46 @@
#
# 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.
#
HARNESS_ENTRY=harness
HARNESS_FILE=MQTT_Ping_harness
PROOF_UID=MQTT_Ping
# Please see test/cbmc/stubs/network_interface_subs.c for
# more information on MAX_NETWORK_SEND_TRIES.
MAX_NETWORK_SEND_TRIES=3
DEFINES += -DMAX_NETWORK_SEND_TRIES=$(MAX_NETWORK_SEND_TRIES)
INCLUDES +=
# Unlike recvExact, sendBuffer is not bounded by the timeout. The loop in
# sendBuffer will continue until all the bytes are sent or a network error
# occurs. Please see NetworkInterfaceReceiveStub in
# test/cbmc/stubs/network_interface_stubs.c for more
# information.
UNWINDSET += __CPROVER_file_local_core_mqtt_c_sendBuffer.0:$(MAX_NETWORK_SEND_TRIES)
PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/sources/mqtt_cbmc_state.c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/stubs/network_interface_stubs.c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/stubs/get_time_stub.c
PROJECT_SOURCES += $(SRCDIR)/source/core_mqtt.c
PROJECT_SOURCES += $(SRCDIR)/source/core_mqtt_serializer.c
include ../Makefile.common

View File

@ -0,0 +1,10 @@
MQTT_Ping proof
==============
This directory contains a memory safety proof for MQTT_Ping.
To run the proof.
* Add cbmc, goto-cc, goto-instrument, goto-analyzer, and cbmc-viewer
to your path.
* Run "make".
* Open html/index.html in a web browser.

View File

@ -0,0 +1 @@
# This file marks this directory as containing a CBMC proof.

View File

@ -0,0 +1,7 @@
{ "expected-missing-functions":
[
],
"proof-name": "MQTT_Ping",
"proof-root": "test/cbmc/proofs"
}

Some files were not shown because too many files have changed in this diff Show More