Merge remote-tracking branch 'adafruit/main' into HEAD

This commit is contained in:
Dan Halbert 2022-10-11 12:21:59 -04:00
commit 851f8a188d
1548 changed files with 43469 additions and 23808 deletions

View File

@ -30,12 +30,12 @@ jobs:
env: env:
GITHUB_CONTEXT: ${{ toJson(github) }} GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT" run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v2.2.0 - uses: actions/checkout@v3
with: with:
submodules: false submodules: false
fetch-depth: 1 fetch-depth: 1
- name: Set up Python 3 - name: Set up Python 3
uses: actions/setup-python@v2 uses: actions/setup-python@v4
with: with:
python-version: "3.x" python-version: "3.x"
- name: Get CP deps - name: Get CP deps
@ -92,25 +92,25 @@ jobs:
working-directory: tests working-directory: tests
- name: Build mpy-cross.static-aarch64 - name: Build mpy-cross.static-aarch64
run: make -C mpy-cross -j2 -f Makefile.static-aarch64 run: make -C mpy-cross -j2 -f Makefile.static-aarch64
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: mpy-cross.static-aarch64 name: mpy-cross.static-aarch64
path: mpy-cross/mpy-cross.static-aarch64 path: mpy-cross/mpy-cross.static-aarch64
- name: Build mpy-cross.static-raspbian - name: Build mpy-cross.static-raspbian
run: make -C mpy-cross -j2 -f Makefile.static-raspbian run: make -C mpy-cross -j2 -f Makefile.static-raspbian
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: mpy-cross.static-raspbian name: mpy-cross.static-raspbian
path: mpy-cross/mpy-cross.static-raspbian path: mpy-cross/mpy-cross.static-raspbian
- name: Build mpy-cross.static - name: Build mpy-cross.static
run: make -C mpy-cross -j2 -f Makefile.static run: make -C mpy-cross -j2 -f Makefile.static
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: mpy-cross.static-amd64-linux name: mpy-cross.static-amd64-linux
path: mpy-cross/mpy-cross.static path: mpy-cross/mpy-cross.static
- name: Build mpy-cross.static-mingw - name: Build mpy-cross.static-mingw
run: make -C mpy-cross -j2 -f Makefile.static-mingw run: make -C mpy-cross -j2 -f Makefile.static-mingw
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: mpy-cross.static-x64-windows name: mpy-cross.static-x64-windows
path: mpy-cross/mpy-cross.static.exe path: mpy-cross/mpy-cross.static.exe
@ -143,18 +143,18 @@ jobs:
mpy-cross-mac: mpy-cross-mac:
runs-on: macos-10.15 runs-on: macos-11
steps: steps:
- name: Dump GitHub context - name: Dump GitHub context
env: env:
GITHUB_CONTEXT: ${{ toJson(github) }} GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT" run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v2.2.0 - uses: actions/checkout@v3
with: with:
submodules: false submodules: false
fetch-depth: 1 fetch-depth: 1
- name: Set up Python 3 - name: Set up Python 3
uses: actions/setup-python@v2 uses: actions/setup-python@v4
with: with:
python-version: "3.x" python-version: "3.x"
- name: Get CP deps - name: Get CP deps
@ -174,29 +174,27 @@ jobs:
msgfmt --version msgfmt --version
- name: Build mpy-cross - name: Build mpy-cross
run: make -C mpy-cross -j2 run: make -C mpy-cross -j2
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: mpy-cross-macos-catalina name: mpy-cross-macos-11-x64
path: mpy-cross/mpy-cross path: mpy-cross/mpy-cross
- name: Select SDK for M1 build
run: sudo xcode-select -switch /Applications/Xcode_12.3.app
- name: Build mpy-cross (arm64) - name: Build mpy-cross (arm64)
run: make -C mpy-cross -j2 -f Makefile.m1 V=2 run: make -C mpy-cross -j2 -f Makefile.m1 V=2
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: mpy-cross-macos-bigsur-arm64 name: mpy-cross-macos-11-arm64
path: mpy-cross/mpy-cross-arm64 path: mpy-cross/mpy-cross-arm64
- name: Make universal binary - name: Make universal binary
run: lipo -create -output mpy-cross-macos-universal mpy-cross/mpy-cross mpy-cross/mpy-cross-arm64 run: lipo -create -output mpy-cross-macos-universal mpy-cross/mpy-cross mpy-cross/mpy-cross-arm64
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: mpy-cross-macos-universal name: mpy-cross-macos-11-universal
path: mpy-cross-macos-universal path: mpy-cross-macos-universal
- name: Upload mpy-cross build to S3 - name: Upload mpy-cross build to S3
run: | run: |
[ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross-macos-universal s3://adafruit-circuit-python/bin/mpy-cross/mpy-cross-macos-universal-${{ env.CP_VERSION }} --no-progress --region us-east-1 [ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross-macos-universal s3://adafruit-circuit-python/bin/mpy-cross/mpy-cross-macos-11-${{ env.CP_VERSION }}-universal --no-progress --region us-east-1
[ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross/mpy-cross-arm64 s3://adafruit-circuit-python/bin/mpy-cross/mpy-cross-macos-bigsur-${{ env.CP_VERSION }}-arm64 --no-progress --region us-east-1 [ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross/mpy-cross-arm64 s3://adafruit-circuit-python/bin/mpy-cross/mpy-cross-macos-11-${{ env.CP_VERSION }}-arm64 --no-progress --region us-east-1
[ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross/mpy-cross s3://adafruit-circuit-python/bin/mpy-cross/mpy-cross-macos-catalina-${{ env.CP_VERSION }} --no-progress --region us-east-1 [ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross/mpy-cross s3://adafruit-circuit-python/bin/mpy-cross/mpy-cross-macos-11-${{ env.CP_VERSION }}-x64 --no-progress --region us-east-1
env: env:
AWS_PAGER: '' AWS_PAGER: ''
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
@ -209,7 +207,7 @@ jobs:
needs: test needs: test
if: ${{ needs.test.outputs.build-doc == 'True' }} if: ${{ needs.test.outputs.build-doc == 'True' }}
steps: steps:
- uses: actions/checkout@v2.2.0 - uses: actions/checkout@v3
with: with:
submodules: false submodules: false
fetch-depth: 1 fetch-depth: 1
@ -220,7 +218,7 @@ jobs:
tools/describe || git log --parents HEAD~4.. tools/describe || git log --parents HEAD~4..
echo >>$GITHUB_ENV CP_VERSION=$(tools/describe) echo >>$GITHUB_ENV CP_VERSION=$(tools/describe)
- name: Set up Python 3 - name: Set up Python 3
uses: actions/setup-python@v2 uses: actions/setup-python@v4
with: with:
python-version: "3.x" python-version: "3.x"
- name: Install dependencies - name: Install dependencies
@ -231,20 +229,20 @@ jobs:
pip install -r requirements-ci.txt -r requirements-doc.txt pip install -r requirements-ci.txt -r requirements-doc.txt
- name: Build and Validate Stubs - name: Build and Validate Stubs
run: make check-stubs -j2 run: make check-stubs -j2
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: stubs name: stubs
path: circuitpython-stubs/dist/* path: circuitpython-stubs/dist/*
- name: Test Documentation Build (HTML) - name: Test Documentation Build (HTML)
run: sphinx-build -E -W -b html -D version=${{ env.CP_VERSION }} -D release=${{ env.CP_VERSION }} . _build/html run: sphinx-build -E -W -b html -D version=${{ env.CP_VERSION }} -D release=${{ env.CP_VERSION }} . _build/html
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: docs name: docs
path: _build/html path: _build/html
- name: Test Documentation Build (LaTeX/PDF) - name: Test Documentation Build (LaTeX/PDF)
run: | run: |
make latexpdf make latexpdf
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: docs name: docs
path: _build/latex path: _build/latex
@ -278,21 +276,22 @@ jobs:
if: ${{ needs.test.outputs.boards-arm != '[]' }} if: ${{ needs.test.outputs.boards-arm != '[]' }}
steps: steps:
- name: Set up Python 3 - name: Set up Python 3
uses: actions/setup-python@v2 uses: actions/setup-python@v4
with: with:
python-version: "3.x" python-version: "3.x"
- uses: actions/checkout@v2.2.0 - uses: actions/checkout@v3
with: with:
submodules: false submodules: false
fetch-depth: 1 fetch-depth: 1
- name: Get CP deps - name: Get CP deps
run: python tools/ci_fetch_deps.py ${{ matrix.board }} ${{ github.sha }} run: python tools/ci_fetch_deps.py ${{ matrix.board }} ${{ github.sha }}
- uses: carlosperate/arm-none-eabi-gcc-action@v1
with:
release: '10-2020-q4'
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt-get install -y gettext sudo apt-get install -y gettext
pip install -r requirements-ci.txt -r requirements-dev.txt pip install -r requirements-ci.txt -r requirements-dev.txt
wget --no-verbose https://adafruit-circuit-python.s3.amazonaws.com/gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2
sudo tar -C /usr --strip-components=1 -xaf gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2
- name: Versions - name: Versions
run: | run: |
gcc --version gcc --version
@ -307,7 +306,7 @@ jobs:
working-directory: tools working-directory: tools
env: env:
BOARDS: ${{ matrix.board }} BOARDS: ${{ matrix.board }}
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: ${{ matrix.board }} name: ${{ matrix.board }}
path: bin/${{ matrix.board }} path: bin/${{ matrix.board }}
@ -330,10 +329,10 @@ jobs:
if: ${{ needs.test.outputs.boards-riscv != '[]' }} if: ${{ needs.test.outputs.boards-riscv != '[]' }}
steps: steps:
- name: Set up Python 3 - name: Set up Python 3
uses: actions/setup-python@v2 uses: actions/setup-python@v4
with: with:
python-version: "3.x" python-version: "3.x"
- uses: actions/checkout@v2.2.0 - uses: actions/checkout@v3
with: with:
submodules: false submodules: false
fetch-depth: 1 fetch-depth: 1
@ -359,7 +358,7 @@ jobs:
working-directory: tools working-directory: tools
env: env:
BOARDS: ${{ matrix.board }} BOARDS: ${{ matrix.board }}
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: ${{ matrix.board }} name: ${{ matrix.board }}
path: bin/${{ matrix.board }} path: bin/${{ matrix.board }}
@ -382,10 +381,11 @@ jobs:
if: ${{ needs.test.outputs.boards-espressif != '[]' }} if: ${{ needs.test.outputs.boards-espressif != '[]' }}
steps: steps:
- name: Set up Python 3 - name: Set up Python 3
uses: actions/setup-python@v2 id: py3
uses: actions/setup-python@v4
with: with:
python-version: "3.x" python-version: "3.x"
- uses: actions/checkout@v2.2.0 - uses: actions/checkout@v3
with: with:
submodules: false submodules: false
fetch-depth: 1 fetch-depth: 1
@ -395,12 +395,12 @@ jobs:
run: | run: |
tools/describe || git log --parents HEAD~4.. tools/describe || git log --parents HEAD~4..
echo >>$GITHUB_ENV CP_VERSION=$(tools/describe) echo >>$GITHUB_ENV CP_VERSION=$(tools/describe)
- uses: actions/cache@v2 - uses: actions/cache@v3
name: Fetch IDF tool cache name: Fetch IDF tool cache
id: idf-cache id: idf-cache
with: with:
path: ${{ github.workspace }}/.idf_tools path: ${{ github.workspace }}/.idf_tools
key: ${{ runner.os }}-idf-tools-${{ hashFiles('.git/modules/ports/espressif/esp-idf/HEAD') }}-20220404 key: ${{ runner.os }}-idf-tools-${{ hashFiles('.git/modules/ports/espressif/esp-idf/HEAD') }}-${{ steps.py3.outputs.python-path }}-20220404
- name: Clone IDF submodules - name: Clone IDF submodules
run: | run: |
(cd $IDF_PATH && git submodule update --init) (cd $IDF_PATH && git submodule update --init)
@ -449,7 +449,7 @@ jobs:
IDF_PATH: ${{ github.workspace }}/ports/espressif/esp-idf IDF_PATH: ${{ github.workspace }}/ports/espressif/esp-idf
IDF_TOOLS_PATH: ${{ github.workspace }}/.idf_tools IDF_TOOLS_PATH: ${{ github.workspace }}/.idf_tools
BOARDS: ${{ matrix.board }} BOARDS: ${{ matrix.board }}
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: ${{ matrix.board }} name: ${{ matrix.board }}
path: bin/${{ matrix.board }} path: bin/${{ matrix.board }}
@ -471,10 +471,10 @@ jobs:
if: ${{ needs.test.outputs.boards-aarch != '[]' }} if: ${{ needs.test.outputs.boards-aarch != '[]' }}
steps: steps:
- name: Set up Python 3 - name: Set up Python 3
uses: actions/setup-python@v2 uses: actions/setup-python@v4
with: with:
python-version: "3.x" python-version: "3.x"
- uses: actions/checkout@v2.2.0 - uses: actions/checkout@v3
with: with:
submodules: false submodules: false
fetch-depth: 1 fetch-depth: 1
@ -486,8 +486,9 @@ jobs:
pip install -r requirements-ci.txt -r requirements-dev.txt pip install -r requirements-ci.txt -r requirements-dev.txt
wget --no-verbose https://adafruit-circuit-python.s3.amazonaws.com/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz wget --no-verbose https://adafruit-circuit-python.s3.amazonaws.com/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz
sudo tar -C /usr --strip-components=1 -xaf gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz sudo tar -C /usr --strip-components=1 -xaf gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz
wget --no-verbose https://adafruit-circuit-python.s3.amazonaws.com/gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2 - uses: carlosperate/arm-none-eabi-gcc-action@v1
sudo tar -C /usr --strip-components=1 -xaf gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2 with:
release: '10-2020-q4'
- name: Install mkfs.fat - name: Install mkfs.fat
run: | run: |
wget https://github.com/dosfstools/dosfstools/releases/download/v4.2/dosfstools-4.2.tar.gz wget https://github.com/dosfstools/dosfstools/releases/download/v4.2/dosfstools-4.2.tar.gz
@ -513,7 +514,7 @@ jobs:
working-directory: tools working-directory: tools
env: env:
BOARDS: ${{ matrix.board }} BOARDS: ${{ matrix.board }}
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: ${{ matrix.board }} name: ${{ matrix.board }}
path: bin/${{ matrix.board }} path: bin/${{ matrix.board }}

View File

@ -16,12 +16,12 @@ jobs:
env: env:
GITHUB_CONTEXT: ${{ toJson(github) }} GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT" run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v2.2.0 - uses: actions/checkout@v3
with: with:
submodules: false submodules: false
fetch-depth: 1 fetch-depth: 1
- name: Set up Python 3 - name: Set up Python 3
uses: actions/setup-python@v2 uses: actions/setup-python@v4
with: with:
python-version: "3.x" python-version: "3.x"
- name: Get CP deps - name: Get CP deps

View File

@ -71,7 +71,7 @@ jobs:
which python; python --version; python -c "import cascadetoml" which python; python --version; python -c "import cascadetoml"
which python3; python3 --version; python3 -c "import cascadetoml" which python3; python3 --version; python3 -c "import cascadetoml"
- uses: actions/checkout@v2.2.0 - uses: actions/checkout@v3
with: with:
submodules: false submodules: false
fetch-depth: 1 fetch-depth: 1

View File

@ -14,33 +14,32 @@ concurrency:
jobs: jobs:
pre-commit: pre-commit:
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v2.2.0 - uses: actions/checkout@v3
- name: Set up Python 3 - name: Set up Python 3
uses: actions/setup-python@v2 uses: actions/setup-python@v4
with: with:
python-version: "3.x" python-version: "3.x"
- name: Install deps - name: Install deps
run: | run: |
sudo apt-add-repository -y -u ppa:pybricks/ppa
sudo apt-get install -y gettext uncrustify sudo apt-get install -y gettext uncrustify
pip3 install black polib pyyaml pip3 install black polib pyyaml
- name: Populate selected submodules - name: Populate selected submodules
run: git submodule update --init extmod/ulab run: git submodule update --init extmod/ulab
- name: Set PY - name: Set PY
run: echo >>$GITHUB_ENV PY="$(python -c 'import hashlib, sys;print(hashlib.sha256(sys.version.encode()+sys.executable.encode()).hexdigest())')" run: echo >>$GITHUB_ENV PY="$(python -c 'import hashlib, sys;print(hashlib.sha256(sys.version.encode()+sys.executable.encode()).hexdigest())')"
- uses: actions/cache@v2 - uses: actions/cache@v3
with: with:
path: ~/.cache/pre-commit path: ~/.cache/pre-commit
key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }} key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }}
- uses: pre-commit/action@v1.1.0 - uses: pre-commit/action@v3.0.0
- name: Make patch - name: Make patch
if: failure() if: failure()
run: git diff > ~/pre-commit.patch run: git diff > ~/pre-commit.patch
- name: Upload patch - name: Upload patch
if: failure() if: failure()
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v3
with: with:
name: patch name: patch
path: ~/pre-commit.patch path: ~/pre-commit.patch

36
.gitmodules vendored
View File

@ -145,10 +145,10 @@
url = https://github.com/adafruit/Adafruit_CircuitPython_RFM69.git url = https://github.com/adafruit/Adafruit_CircuitPython_RFM69.git
[submodule "ports/espressif/esp-idf"] [submodule "ports/espressif/esp-idf"]
path = ports/espressif/esp-idf path = ports/espressif/esp-idf
url = https://github.com/espressif/esp-idf.git url = https://github.com/adafruit/esp-idf.git
branch = release/v4.4 branch = circuitpython8
[submodule "ports/espressif/certificates/nina-fw"] [submodule "ports/espressif/certificates/nina-fw"]
path = ports/espressif/certificates/nina-fw path = lib/certificates/nina-fw
url = https://github.com/adafruit/nina-fw.git url = https://github.com/adafruit/nina-fw.git
[submodule "frozen/Adafruit_CircuitPython_ST7789"] [submodule "frozen/Adafruit_CircuitPython_ST7789"]
path = frozen/Adafruit_CircuitPython_ST7789 path = frozen/Adafruit_CircuitPython_ST7789
@ -289,3 +289,33 @@
[submodule "frozen/pew-pewpew-lcd"] [submodule "frozen/pew-pewpew-lcd"]
path = frozen/pew-pewpew-lcd path = frozen/pew-pewpew-lcd
url = https://github.com/pypewpew/pew-pewpew-lcd.git url = https://github.com/pypewpew/pew-pewpew-lcd.git
[submodule "frozen/mixgo_cp_lib"]
path = frozen/mixgo_cp_lib
url = https://github.com/dahanzimin/circuitpython_lib.git
[submodule "frozen/Adafruit_CircuitPython_IS31FL3731"]
path = frozen/Adafruit_CircuitPython_IS31FL3731
url = https://github.com/adafruit/Adafruit_CircuitPython_IS31FL3731.git
[submodule "frozen/Adafruit_CircuitPython_Ticks"]
path = frozen/Adafruit_CircuitPython_Ticks
url = https://github.com/adafruit/Adafruit_CircuitPython_Ticks.git
[submodule "frozen/Adafruit_CircuitPython_asyncio"]
path = frozen/Adafruit_CircuitPython_asyncio
url = https://github.com/adafruit/Adafruit_CircuitPython_asyncio.git
[submodule "frozen/circuitpython_ef_music"]
path = frozen/circuitpython_ef_music
url = https://github.com/elecfreaks/circuitpython_ef_music.git
[submodule "frozen/circuitpython_picoed"]
path = frozen/circuitpython_picoed
url = https://github.com/elecfreaks/circuitpython_picoed.git
[submodule "ports/espressif/esp32-camera"]
path = ports/espressif/esp32-camera
url = https://github.com/adafruit/esp32-camera/
[submodule "ports/raspberrypi/lib/cyw43-driver"]
path = ports/raspberrypi/lib/cyw43-driver
url = https://github.com/georgerobotics/cyw43-driver.git
[submodule "ports/raspberrypi/lib/lwip"]
path = ports/raspberrypi/lib/lwip
url = https://github.com/lwip-tcpip/lwip.git
[submodule "lib/mbedtls"]
path = lib/mbedtls
url = https://github.com/ARMmbed/mbedtls.git

View File

@ -10,7 +10,7 @@ repos:
- id: end-of-file-fixer - id: end-of-file-fixer
exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*|ports/espressif/esp-idf-config/.*|ports/espressif/boards/.*/sdkconfig)' exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*|ports/espressif/esp-idf-config/.*|ports/espressif/boards/.*/sdkconfig)'
- id: trailing-whitespace - id: trailing-whitespace
exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*)' exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*|lib/mbedtls_errors/.*)'
- repo: local - repo: local
hooks: hooks:
- id: translations - id: translations

View File

@ -70,7 +70,7 @@ The test suite in the top level `tests` directory. It needs the unix port to ru
Then you can run the test suite: Then you can run the test suite:
cd ../../tests cd ../../tests
./run-tests ./run-tests.py
A successful run will say something like A successful run will say something like

76
LICENSE
View File

@ -1,6 +1,6 @@
The MIT License (MIT) MIT License
Copyright (c) 2013-2022 Damien P. George Copyright (c) 2013-2022 Damien P. George and others
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@ -9,77 +9,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in all
all copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
THE SOFTWARE. SOFTWARE.
--------------------------------------------------------------------------------
Unless specified otherwise (see below), the above license and copyright applies
to all files in this repository.
Individual files may include additional copyright holders.
The various ports of MicroPython may include third-party software that is
licensed under different terms. These licenses are summarised in the tree
below, please refer to these files and directories for further license and
copyright information. Note that (L)GPL-licensed code listed below is only
used during the build process and is not part of the compiled source code.
/ (MIT)
/drivers
/cc3000 (BSD-3-clause)
/cc3100 (BSD-3-clause)
/wiznet5k (BSD-3-clause)
/lib
/asf4 (Apache-2.0)
/axtls (BSD-3-clause)
/config
/scripts
/config (GPL-2.0-or-later)
/Rules.mak (GPL-2.0)
/berkeley-db-1xx (BSD-4-clause)
/btstack (See btstack/LICENSE)
/cmsis (BSD-3-clause)
/crypto-algorithms (NONE)
/libhydrogen (ISC)
/littlefs (BSD-3-clause)
/lwip (BSD-3-clause)
/mynewt-nimble (Apache-2.0)
/nrfx (BSD-3-clause)
/nxp_driver (BSD-3-Clause)
/oofatfs (BSD-1-clause)
/pico-sdk (BSD-3-clause)
/re15 (BSD-3-clause)
/stm32lib (BSD-3-clause)
/tinytest (BSD-3-clause)
/tinyusb (MIT)
/uzlib (Zlib)
/logo (uses OFL-1.1)
/ports
/cc3200
/hal (BSD-3-clause)
/simplelink (BSD-3-clause)
/FreeRTOS (GPL-2.0 with FreeRTOS exception)
/stm32
/usbd*.c (MCD-ST Liberty SW License Agreement V2)
/stm32_it.* (MIT + BSD-3-clause)
/system_stm32*.c (MIT + BSD-3-clause)
/boards
/startup_stm32*.s (BSD-3-clause)
/*/stm32*.h (BSD-3-clause)
/usbdev (MCD-ST Liberty SW License Agreement V2)
/usbhost (MCD-ST Liberty SW License Agreement V2)
/teensy
/core (PJRC.COM)
/zephyr
/src (Apache-2.0)
/tools
/dfu.py (LGPL-3.0-only)

85
LICENSE_MicroPython Normal file
View File

@ -0,0 +1,85 @@
The MIT License (MIT)
Copyright (c) 2013-2022 Damien P. George
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.
--------------------------------------------------------------------------------
Unless specified otherwise (see below), the above license and copyright applies
to all files in this repository.
Individual files may include additional copyright holders.
The various ports of MicroPython may include third-party software that is
licensed under different terms. These licenses are summarised in the tree
below, please refer to these files and directories for further license and
copyright information. Note that (L)GPL-licensed code listed below is only
used during the build process and is not part of the compiled source code.
/ (MIT)
/drivers
/cc3000 (BSD-3-clause)
/cc3100 (BSD-3-clause)
/wiznet5k (BSD-3-clause)
/lib
/asf4 (Apache-2.0)
/axtls (BSD-3-clause)
/config
/scripts
/config (GPL-2.0-or-later)
/Rules.mak (GPL-2.0)
/berkeley-db-1xx (BSD-4-clause)
/btstack (See btstack/LICENSE)
/cmsis (BSD-3-clause)
/crypto-algorithms (NONE)
/libhydrogen (ISC)
/littlefs (BSD-3-clause)
/lwip (BSD-3-clause)
/mynewt-nimble (Apache-2.0)
/nrfx (BSD-3-clause)
/nxp_driver (BSD-3-Clause)
/oofatfs (BSD-1-clause)
/pico-sdk (BSD-3-clause)
/re15 (BSD-3-clause)
/stm32lib (BSD-3-clause)
/tinytest (BSD-3-clause)
/tinyusb (MIT)
/uzlib (Zlib)
/logo (uses OFL-1.1)
/ports
/cc3200
/hal (BSD-3-clause)
/simplelink (BSD-3-clause)
/FreeRTOS (GPL-2.0 with FreeRTOS exception)
/stm32
/usbd*.c (MCD-ST Liberty SW License Agreement V2)
/stm32_it.* (MIT + BSD-3-clause)
/system_stm32*.c (MIT + BSD-3-clause)
/boards
/startup_stm32*.s (BSD-3-clause)
/*/stm32*.h (BSD-3-clause)
/usbdev (MCD-ST Liberty SW License Agreement V2)
/usbhost (MCD-ST Liberty SW License Agreement V2)
/teensy
/core (PJRC.COM)
/zephyr
/src (Apache-2.0)
/tools
/dfu.py (LGPL-3.0-only)

View File

@ -84,15 +84,19 @@ common set of requirements.
If you'd like to use the term "CircuitPython" and Blinka for your product here is what we ask: If you'd like to use the term "CircuitPython" and Blinka for your product here is what we ask:
* Your product is supported by the primary - Your product is supported by the primary
`"adafruit/circuitpython" <https://github.com/adafruit/circuitpython>`_ repo. This way we can `"adafruit/circuitpython" <https://github.com/adafruit/circuitpython>`_ repo. This way we can
update any custom code as we update the CircuitPython internals. update any custom code as we update the CircuitPython internals.
* Your product is listed on `circuitpython.org <https://circuitpython.org>`__ (source - Your product is listed on `circuitpython.org <https://circuitpython.org>`__ (source
`here <https://github.com/adafruit/circuitpython-org/>`_). This is to ensure that a user of your `here <https://github.com/adafruit/circuitpython-org/>`_). This is to ensure that a user of your
product can always download the latest version of CircuitPython from the standard place. product can always download the latest version of CircuitPython from the standard place.
* Your product has a user accessible USB plug which appears as a CIRCUITPY drive when plugged in - Your product supports at least one standard "`Workflow <https://docs.circuitpython.org/en/latest/docs/workflows.html>`__" for serial and file access:
AND/OR provides file and serial access over Bluetooth Low Energy. Boards that do not support USB
should be clearly marked as BLE-only CircuitPython. - With a user accessible USB plug which appears as a CIRCUITPY drive when plugged in.
- With file and serial access over Bluetooth Low Energy using the BLE Workflow.
- With file access over WiFi using the WiFi Workflow with serial access over USB and/or WebSocket.
- Boards that do not support the USB Workflow should be clearly marked.
If you choose not to meet these requirements, then we ask you call your version of CircuitPython If you choose not to meet these requirements, then we ask you call your version of CircuitPython
something else (for example, SuperDuperPython) and not use the Blinka logo. You can say it is something else (for example, SuperDuperPython) and not use the Blinka logo. You can say it is
@ -120,7 +124,7 @@ Behavior
make each file independent from each other. make each file independent from each other.
- ``boot.py`` runs only once on start up before - ``boot.py`` runs only once on start up before
USB is initialized. This lays the ground work for configuring USB at workflows are initialized. This lays the ground work for configuring USB at
startup rather than it being fixed. Since serial is not available, startup rather than it being fixed. Since serial is not available,
output is written to ``boot_out.txt``. output is written to ``boot_out.txt``.
- ``code.py`` (or ``main.py``) is run after every reload until it - ``code.py`` (or ``main.py``) is run after every reload until it
@ -135,7 +139,10 @@ Behavior
possible to fix code that causes nasty crashes by making it available through mass storage after possible to fix code that causes nasty crashes by making it available through mass storage after
the crash. A reset (the button) is needed after it's fixed to get back into normal mode. the crash. A reset (the button) is needed after it's fixed to get back into normal mode.
- RGB status LED indicating CircuitPython state. - RGB status LED indicating CircuitPython state.
- Re-runs ``code.py`` or other main file after file system writes over USB mass storage. (Disable with - One green flash - code completed without error.
- Two red flashes - code ended due to an exception.
- Three yellow flashes - safe mode. May be due to CircuitPython internal error.
- Re-runs ``code.py`` or other main file after file system writes by a workflow. (Disable with
``supervisor.disable_autoreload()``) ``supervisor.disable_autoreload()``)
- Autoreload is disabled while the REPL is active. - Autoreload is disabled while the REPL is active.
- Main is one of these: ``code.txt``, ``code.py``, ``main.py``, - Main is one of these: ``code.txt``, ``code.py``, ``main.py``,
@ -213,7 +220,7 @@ Supported Support status
================ ============================================================ ================ ============================================================
atmel-samd ``SAMD21`` stable | ``SAMD51`` stable atmel-samd ``SAMD21`` stable | ``SAMD51`` stable
cxd56 stable cxd56 stable
espressif ``ESP32-C3`` beta | ``ESP32-S2`` stable | ``ESP32-S3`` beta espressif ``ESP32`` beta | ``ESP32-C3`` beta | ``ESP32-S2`` stable | ``ESP32-S3`` beta
litex alpha litex alpha
mimxrt10xx alpha mimxrt10xx alpha
nrf stable nrf stable

View File

@ -52,8 +52,8 @@ subprocess.check_output(["make", "stubs"])
#modules_support_matrix = shared_bindings_matrix.support_matrix_excluded_boards() #modules_support_matrix = shared_bindings_matrix.support_matrix_excluded_boards()
modules_support_matrix = shared_bindings_matrix.support_matrix_by_board() modules_support_matrix = shared_bindings_matrix.support_matrix_by_board()
modules_support_matrix_reverse = defaultdict(list) modules_support_matrix_reverse = defaultdict(list)
for board, modules in modules_support_matrix.items(): for board, matrix_info in modules_support_matrix.items():
for module in modules[0]: for module in matrix_info["modules"]:
modules_support_matrix_reverse[module].append(board) modules_support_matrix_reverse[module].append(board)
modules_support_matrix_reverse = dict( modules_support_matrix_reverse = dict(
@ -199,6 +199,7 @@ exclude_patterns = ["**/build*",
"ports/cxd56/spresense-exported-sdk", "ports/cxd56/spresense-exported-sdk",
"ports/espressif/certificates", "ports/espressif/certificates",
"ports/espressif/esp-idf", "ports/espressif/esp-idf",
"ports/espressif/esp32-camera",
"ports/espressif/.idf_tools", "ports/espressif/.idf_tools",
"ports/espressif/peripherals", "ports/espressif/peripherals",
"ports/litex/hw", "ports/litex/hw",
@ -212,6 +213,7 @@ exclude_patterns = ["**/build*",
"ports/nrf/peripherals", "ports/nrf/peripherals",
"ports/nrf/usb", "ports/nrf/usb",
"ports/raspberrypi/sdk", "ports/raspberrypi/sdk",
"ports/raspberrypi/lib",
"ports/stm/st_driver", "ports/stm/st_driver",
"ports/stm/packages", "ports/stm/packages",
"ports/stm/peripherals", "ports/stm/peripherals",

@ -1 +1 @@
Subproject commit 266ea20ed80104c315dcb124b482fa5f9f48cdec Subproject commit 2d292ad4e67890d4b85b027431ba9fef7bf561fd

View File

@ -49,6 +49,10 @@
#include "shared-bindings/_bleio/ScanEntry.h" #include "shared-bindings/_bleio/ScanEntry.h"
#include "shared-bindings/time/__init__.h" #include "shared-bindings/time/__init__.h"
#if CIRCUITPY_DOTENV
#include "shared-module/dotenv/__init__.h"
#endif
#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION)) #define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION))
#define SEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000000) / (RESOLUTION)) #define SEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000000) / (RESOLUTION))
#define UNITS_TO_SEC(TIME, RESOLUTION) (((TIME)*(RESOLUTION)) / 1000000) #define UNITS_TO_SEC(TIME, RESOLUTION) (((TIME)*(RESOLUTION)) / 1000000)
@ -278,17 +282,27 @@ char default_ble_name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 0, 0, 0
// Get various values and limits set by the adapter. // Get various values and limits set by the adapter.
// Set event mask. // Set event mask.
STATIC void bleio_adapter_hci_init(bleio_adapter_obj_t *self) { STATIC void bleio_adapter_hci_init(bleio_adapter_obj_t *self) {
mp_int_t name_len = 0;
const size_t len = sizeof(default_ble_name); #if CIRCUITPY_DOTENV
char ble_name[32];
name_len = dotenv_get_key("/.env", "CIRCUITPY_BLE_NAME", ble_name, sizeof(ble_name) - 1);
if (name_len > 0) {
self->name = mp_obj_new_str(ble_name, (size_t)name_len);
}
#endif
bt_addr_t addr; if (name_len <= 0) {
hci_check_error(hci_read_bd_addr(&addr)); name_len = sizeof(default_ble_name);
bt_addr_t addr;
hci_check_error(hci_read_bd_addr(&addr));
default_ble_name[len - 4] = nibble_to_hex_lower[addr.val[1] >> 4 & 0xf]; default_ble_name[name_len - 4] = nibble_to_hex_lower[addr.val[1] >> 4 & 0xf];
default_ble_name[len - 3] = nibble_to_hex_lower[addr.val[1] & 0xf]; default_ble_name[name_len - 3] = nibble_to_hex_lower[addr.val[1] & 0xf];
default_ble_name[len - 2] = nibble_to_hex_lower[addr.val[0] >> 4 & 0xf]; default_ble_name[name_len - 2] = nibble_to_hex_lower[addr.val[0] >> 4 & 0xf];
default_ble_name[len - 1] = nibble_to_hex_lower[addr.val[0] & 0xf]; default_ble_name[name_len - 1] = nibble_to_hex_lower[addr.val[0] & 0xf];
self->name = mp_obj_new_str(default_ble_name, len); self->name = mp_obj_new_str(default_ble_name, (uint8_t)name_len);
}
// Get version information. // Get version information.
if (hci_read_local_version(&self->hci_version, &self->hci_revision, &self->lmp_version, if (hci_read_local_version(&self->hci_version, &self->hci_revision, &self->lmp_version,

View File

@ -57,9 +57,9 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self,
self->value = mp_obj_new_bytes(initial_value_bufinfo->buf, initial_value_bufinfo->len); self->value = mp_obj_new_bytes(initial_value_bufinfo->buf, initial_value_bufinfo->len);
const mp_int_t max_length_max = 512; const mp_int_t max_length_max = 512;
if (max_length < 0 || max_length > max_length_max) {
mp_raise_ValueError(translate("max_length must be <= 512")); mp_arg_validate_int_range(max_length, 0, max_length_max, MP_QSTR_max_length);
}
self->max_length = max_length; self->max_length = max_length;
self->fixed_length = fixed_length; self->fixed_length = fixed_length;

View File

@ -93,6 +93,7 @@ bool common_hal_bleio_characteristic_buffer_deinited(bleio_characteristic_buffer
void common_hal_bleio_characteristic_buffer_deinit(bleio_characteristic_buffer_obj_t *self) { void common_hal_bleio_characteristic_buffer_deinit(bleio_characteristic_buffer_obj_t *self) {
if (!common_hal_bleio_characteristic_buffer_deinited(self)) { if (!common_hal_bleio_characteristic_buffer_deinited(self)) {
bleio_characteristic_clear_observer(self->characteristic); bleio_characteristic_clear_observer(self->characteristic);
ringbuf_deinit(&self->ringbuf);
} }
} }

View File

@ -37,13 +37,13 @@
#include "supervisor/shared/tick.h" #include "supervisor/shared/tick.h"
STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uint16_t len) { STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uint16_t len) {
if (len + sizeof(uint16_t) > ringbuf_capacity(&self->ringbuf)) { if (len + sizeof(uint16_t) > ringbuf_size(&self->ringbuf)) {
// This shouldn't happen. // This shouldn't happen.
return; return;
} }
// Push all the data onto the ring buffer. // Push all the data onto the ring buffer.
// Make room for the new value by dropping the oldest packets first. // Make room for the new value by dropping the oldest packets first.
while (ringbuf_capacity(&self->ringbuf) - ringbuf_num_filled(&self->ringbuf) < len + sizeof(uint16_t)) { while (ringbuf_size(&self->ringbuf) - ringbuf_num_filled(&self->ringbuf) < len + sizeof(uint16_t)) {
uint16_t packet_length; uint16_t packet_length;
ringbuf_get_n(&self->ringbuf, (uint8_t *)&packet_length, sizeof(uint16_t)); ringbuf_get_n(&self->ringbuf, (uint8_t *)&packet_length, sizeof(uint16_t));
for (uint16_t i = 0; i < packet_length; i++) { for (uint16_t i = 0; i < packet_length; i++) {
@ -264,5 +264,6 @@ bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self) {
void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self) { void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self) {
if (!common_hal_bleio_packet_buffer_deinited(self)) { if (!common_hal_bleio_packet_buffer_deinited(self)) {
bleio_characteristic_clear_observer(self->characteristic); bleio_characteristic_clear_observer(self->characteristic);
ringbuf_deinit(&self->ringbuf);
} }
} }

View File

@ -44,6 +44,7 @@
#include "shared-bindings/_bleio/Service.h" #include "shared-bindings/_bleio/Service.h"
#include "shared-bindings/_bleio/UUID.h" #include "shared-bindings/_bleio/UUID.h"
#include "supervisor/shared/tick.h" #include "supervisor/shared/tick.h"
#include "supervisor/shared/translate/translate.h"
STATIC uint16_t max_mtu = BT_ATT_DEFAULT_LE_MTU; // 23 STATIC uint16_t max_mtu = BT_ATT_DEFAULT_LE_MTU; // 23
STATIC unsigned long timeout = 5000; STATIC unsigned long timeout = 5000;

View File

@ -1,9 +1,8 @@
MicroPython & CircuitPython license information # MicroPython & CircuitPython License
===============================================
The MIT License (MIT) MIT License
Copyright (c) 2013-2017 Damien P. George, and others Copyright (c) 2013-2022 Damien P. George and others
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@ -12,13 +11,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in all
all copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
THE SOFTWARE. SOFTWARE.

View File

@ -141,7 +141,7 @@ statement will ensure hardware isn't enabled longer than needed.
Verify your device Verify your device
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
Whenever possible, make sure device you are talking to is the device you expect. Whenever possible, make sure the device you are talking to is the device you expect.
If not, raise a RuntimeError. Beware that I2C addresses can be identical on If not, raise a RuntimeError. Beware that I2C addresses can be identical on
different devices so read registers you know to make sure they match your different devices so read registers you know to make sure they match your
expectation. Validating this upfront will help catch mistakes. expectation. Validating this upfront will help catch mistakes.
@ -202,10 +202,10 @@ interchangeably with the CPython name. This is confusing. Instead, think up a
new name that is related to the extra functionality you are adding. new name that is related to the extra functionality you are adding.
For example, storage mounting and unmounting related functions were moved from For example, storage mounting and unmounting related functions were moved from
``uos`` into a new `storage` module. Terminal related functions were moved into ``uos`` into a new `storage` module. These names better match their
`multiterminal`. These names better match their functionality and do not functionality and do not conflict with CPython names. Make sure to check that
conflict with CPython names. Make sure to check that you don't conflict with you don't conflict with CPython libraries too. That way we can port the API to
CPython libraries too. That way we can port the API to CPython in the future. CPython in the future.
Example Example
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -213,7 +213,7 @@ Example
When adding extra functionality to CircuitPython to mimic what a normal When adding extra functionality to CircuitPython to mimic what a normal
operating system would do, either copy an existing CPython API (for example file operating system would do, either copy an existing CPython API (for example file
writing) or create a separate module to achieve what you want. For example, writing) or create a separate module to achieve what you want. For example,
mounting and unmount drives is not a part of CPython so it should be done in a mounting and unmounting drives is not a part of CPython so it should be done in a
module, such as a new ``storage`` module, that is only available in CircuitPython. module, such as a new ``storage`` module, that is only available in CircuitPython.
That way when someone moves the code to CPython they know what parts need to be That way when someone moves the code to CPython they know what parts need to be
adapted. adapted.
@ -309,7 +309,7 @@ following structure:
param_type param_type
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The type of the parameter. This could be among other `int`, `float`, `str` `bool`, etc. The type of the parameter. This could be, among others, ``int``, ``float``, ``str``, ``bool``, etc.
To document an object in the CircuitPython domain, you need to include a ``~`` before the To document an object in the CircuitPython domain, you need to include a ``~`` before the
definition as shown in the following example: definition as shown in the following example:
@ -494,6 +494,45 @@ backticks ``:class:`~adafruit_motor.servo.Servo```. You must also add the refer
"adafruit_motor": ("https://circuitpython.readthedocs.io/projects/motor/en/latest/", None,), "adafruit_motor": ("https://circuitpython.readthedocs.io/projects/motor/en/latest/", None,),
Use ``adafruit_register`` when possible
--------------------------------------------------------------------------------
`Register <https://github.com/adafruit/Adafruit_CircuitPython_Register>`_ is
a foundational library that manages packing and unpacking data from I2C device
registers. There is also `Register SPI <https://github.com/adafruit/Adafruit_CircuitPython_Register_SPI>`_
for SPI devices. When possible, use one of these libraries for unpacking and
packing registers. This ensures the packing code is shared amongst all
registers (even across drivers). Furthermore, it simplifies device definitions
by making them declarative (only data.)
Values with non-consecutive bits in a register or that represent FIFO endpoints
may not map well to existing register classes. In unique cases like these, it is
ok to read and write the register directly.
*Do not* add all registers from a datasheet upfront. Instead, only add the ones
necessary for the functionality the driver exposes. Adding them all will lead to
unnecessary file size and API clutter. See `this video about outside-in design
from @tannewt <https://www.youtube.com/watch?v=3QewiyfBQh8>`_.
I2C Example
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
from adafruit_register import i2c_bit
from adafruit_bus_device import i2c_device
class HelloWorldDevice:
"""Device with two bits to control when the words 'hello' and 'world' are lit."""
hello = i2c_bit.RWBit(0x0, 0x0)
"""Bit to indicate if hello is lit."""
world = i2c_bit.RWBit(0x1, 0x0)
"""Bit to indicate if world is lit."""
def __init__(self, i2c, device_address=0x0):
self.i2c_device = i2c_device.I2CDevice(i2c, device_address)
Use BusDevice Use BusDevice
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -668,8 +707,24 @@ when using ``const()``, keep in mind these general guide lines:
- Always use via an import, ex: ``from micropython import const`` - Always use via an import, ex: ``from micropython import const``
- Limit use to global (module level) variables only. - Limit use to global (module level) variables only.
- If user will not need access to variable, prefix name with a leading - Only used when the user will not need access to variable and prefix name with
underscore, ex: ``_SOME_CONST``. a leading underscore, ex: ``_SOME_CONST``.
Example
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
from adafruit_bus_device import i2c_device
from micropython import const
_DEFAULT_I2C_ADDR = const(0x42)
class Widget:
"""A generic widget."""
def __init__(self, i2c, address=_DEFAULT_I2C_ADDR):
self.i2c_device = i2c_device.I2CDevice(i2c, address)
Libraries Examples Libraries Examples
------------------ ------------------
@ -751,6 +806,16 @@ properties.
| ``sound_level`` | float | non-unit-specific sound level (monotonic but not actual decibels) | | ``sound_level`` | float | non-unit-specific sound level (monotonic but not actual decibels) |
+-----------------------+-----------------------+-------------------------------------------------------------------------+ +-----------------------+-----------------------+-------------------------------------------------------------------------+
Driver constant naming
--------------------------------------------------------------------------------
When adding variables for constant values for a driver. Do not include the
device's name in the variable name. For example, in ``adafruit_fancy123.py``,
variables should not start with ``FANCY123_``. Adding this prefix increases RAM
usage and .mpy file size because variable names are preserved. User code should
refer to these constants as ``adafruit_fancy123.HELLO_WORLD`` for clarity.
``adafruit_fancy123.FANCY123_HELLO_WORLD`` would be overly verbose.
Adding native modules Adding native modules
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

58
docs/environment.rst Normal file
View File

@ -0,0 +1,58 @@
Environment Variables
=====================
CircuitPython 8.0.0 introduces support for environment variables. Environment
variables are commonly used to store "secrets" such as Wi-Fi passwords and API
keys. This method *does not* make them secure. It only separates them from the
code.
CircuitPython supports these by mimicking the `dotenv <https://github.com/theskumar/python-dotenv>`_
CPython library. Other languages such as Javascript, PHP and Ruby also have
dotenv libraries.
These libraries store environment variables in a ``.env`` file. Here is a simple
example:
.. code-block:: bash
KEY1='value1'
# Comment
KEY2='value2
is multiple lines'
CircuitPython uses the ``.env`` at the drive root (no folder) as the environment.
User code can access the values from the file using `os.getenv()`. It is
recommended to save any values used repeatedly in a variable because `os.getenv()`
will parse the ``/.env`` on every access.
CircuitPython behavior
----------------------
CircuitPython will also read the environment to configure its behavior. Other
keys are ignored by CircuitPython. Here are the keys it uses:
CIRCUITPY_BLE_NAME
~~~~~~~~~~~~~~~~~~
Default BLE name the board advertises as, including for the BLE workflow.
CIRCUITPY_RESERVED_PSRAM
~~~~~~~~~~~~~~~~~~~~~~~~
On boards with Espressif microcontrollers with PSRAM (also called SPIRAM), permanently reserve a portion of PSRAM for use by esp-idf.
This storage is removed from the CircuitPython "heap" and is available for allocation by esp-idf routines in the core instead.
Generally, only set this to a non-zero value when it is required by a specific core module.
CIRCUITPY_WEB_API_PASSWORD
~~~~~~~~~~~~~~~~~~~~~~~~~~
Password required to make modifications to the board from the Web Workflow.
CIRCUITPY_WEB_API_PORT
~~~~~~~~~~~~~~~~~~~~~~
TCP port number used for the web HTTP API. Defaults to 80 when omitted.
CIRCUITPY_WIFI_PASSWORD
~~~~~~~~~~~~~~~~~~~~~~~
Wi-Fi password used to auto connect to CIRCUITPY_WIFI_SSID.
CIRCUITPY_WIFI_SSID
~~~~~~~~~~~~~~~~~~~
Wi-Fi SSID to auto-connect to even if user code is not running.

View File

@ -22,6 +22,8 @@ Full Table of Contents
supported_ports.rst supported_ports.rst
troubleshooting.rst troubleshooting.rst
drivers.rst drivers.rst
workflows
environment.rst
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
@ -46,7 +48,7 @@ Full Table of Contents
../CONTRIBUTING ../CONTRIBUTING
../BUILDING ../BUILDING
../CODE_OF_CONDUCT ../CODE_OF_CONDUCT
../license.rst ../docs/LICENSE
../WEBUSB_README ../WEBUSB_README
Indices and tables Indices and tables

View File

@ -1,8 +1,11 @@
:mod:`builtins` -- builtin functions and exceptions :mod:`builtins` -- builtin functions and exceptions
=================================================== ===================================================
.. module:: builtins
:synopsis: builtin Python functions
All builtin functions and exceptions are described here. They are also All builtin functions and exceptions are described here. They are also
available via ``builtins`` module. available via the ``builtins`` module.
For more information about built-ins, see the following CPython documentation: For more information about built-ins, see the following CPython documentation:

View File

@ -28,7 +28,7 @@ Classes
- The optional *flags* can be 1 to check for overflow when adding items. - The optional *flags* can be 1 to check for overflow when adding items.
As well as supporting `bool` and `len`, deque objects have the following As well as supporting ``bool`` and ``len``, deque objects have the following
methods: methods:
.. method:: deque.append(x) .. method:: deque.append(x)

View File

@ -5,6 +5,7 @@
.. module:: hashlib .. module:: hashlib
:synopsis: hashing algorithms :synopsis: hashing algorithms
:noindex:
|see_cpython_module| :mod:`cpython:hashlib`. |see_cpython_module| :mod:`cpython:hashlib`.

View File

@ -76,7 +76,7 @@ Functions
.. function:: heap_locked() .. function:: heap_locked()
Lock or unlock the heap. When locked no memory allocation can occur and a Lock or unlock the heap. When locked no memory allocation can occur and a
`MemoryError` will be raised if any heap allocation is attempted. ``MemoryError`` will be raised if any heap allocation is attempted.
`heap_locked()` returns a true value if the heap is currently locked. `heap_locked()` returns a true value if the heap is currently locked.
These functions can be nested, ie `heap_lock()` can be called multiple times These functions can be nested, ie `heap_lock()` can be called multiple times

View File

@ -71,7 +71,7 @@ as a natural "TODO" list. An example minimal build list is shown below:
CIRCUITPY_SDCARDIO = 0 CIRCUITPY_SDCARDIO = 0
CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_FRAMEBUFFERIO = 0
CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CPERIPHERAL = 0 CIRCUITPY_I2CTARGET = 0
# Requires SPI, PulseIO (stub ok): # Requires SPI, PulseIO (stub ok):
CIRCUITPY_DISPLAYIO = 0 CIRCUITPY_DISPLAYIO = 0
@ -79,8 +79,6 @@ as a natural "TODO" list. An example minimal build list is shown below:
# any port once their prerequisites in common-hal are complete. # any port once their prerequisites in common-hal are complete.
# Requires DigitalIO: # Requires DigitalIO:
CIRCUITPY_BITBANGIO = 0 CIRCUITPY_BITBANGIO = 0
# Requires DigitalIO
CIRCUITPY_GAMEPADSHIFT = 0
# Requires neopixel_write or SPI (dotstar) # Requires neopixel_write or SPI (dotstar)
CIRCUITPY_PIXELBUF = 0 CIRCUITPY_PIXELBUF = 0
# Requires OS # Requires OS

View File

@ -45,12 +45,10 @@ shared-bindings/audiomp3/__init__.rst shared-bindings/audiomp3/
shared-bindings/audiopwmio/PWMAudioOut.rst shared-bindings/audiopwmio/#audiopwmio.PWMAudioOut shared-bindings/audiopwmio/PWMAudioOut.rst shared-bindings/audiopwmio/#audiopwmio.PWMAudioOut
shared-bindings/audiopwmio/__init__.rst shared-bindings/audiopwmio/ shared-bindings/audiopwmio/__init__.rst shared-bindings/audiopwmio/
shared-bindings/bitbangio/I2C.rst shared-bindings/bitbangio/#bitbangio.I2C shared-bindings/bitbangio/I2C.rst shared-bindings/bitbangio/#bitbangio.I2C
shared-bindings/bitbangio/OneWire.rst shared-bindings/bitbangio/#bitbangio.OneWire
shared-bindings/bitbangio/SPI.rst shared-bindings/bitbangio/#bitbangio.SPI shared-bindings/bitbangio/SPI.rst shared-bindings/bitbangio/#bitbangio.SPI
shared-bindings/bitbangio/__init__.rst shared-bindings/bitbangio/ shared-bindings/bitbangio/__init__.rst shared-bindings/bitbangio/
shared-bindings/board/__init__.rst shared-bindings/board/ shared-bindings/board/__init__.rst shared-bindings/board/
shared-bindings/busio/I2C.rst shared-bindings/busio/#busio.I2C shared-bindings/busio/I2C.rst shared-bindings/busio/#busio.I2C
shared-bindings/busio/OneWire.rst shared-bindings/busio/#busio.OneWire
shared-bindings/busio/Parity.rst shared-bindings/busio/#busio.Parity shared-bindings/busio/Parity.rst shared-bindings/busio/#busio.Parity
shared-bindings/busio/SPI.rst shared-bindings/busio/#busio.SPI shared-bindings/busio/SPI.rst shared-bindings/busio/#busio.SPI
shared-bindings/busio/UART.rst shared-bindings/busio/#busio.UART shared-bindings/busio/UART.rst shared-bindings/busio/#busio.UART
@ -82,10 +80,6 @@ shared-bindings/framebufferio/FramebufferDisplay.rst shared-bindings/framebuffer
shared-bindings/framebufferio/__init__.rst shared-bindings/framebufferio/ shared-bindings/framebufferio/__init__.rst shared-bindings/framebufferio/
shared-bindings/frequencyio/FrequencyIn.rst shared-bindings/frequencyio/#frequencyio.FrequencyIn shared-bindings/frequencyio/FrequencyIn.rst shared-bindings/frequencyio/#frequencyio.FrequencyIn
shared-bindings/frequencyio/__init__.rst shared-bindings/frequencyio/ shared-bindings/frequencyio/__init__.rst shared-bindings/frequencyio/
shared-bindings/gamepad/GamePad.rst shared-bindings/gamepad/#gamepad.GamePad
shared-bindings/gamepad/__init__.rst shared-bindings/gamepad/
shared-bindings/gamepadshift/GamePadShift.rst shared-bindings/gamepadshift/#gamepadshift.GamePadShift
shared-bindings/gamepadshift/__init__.rst shared-bindings/gamepadshift/
shared-bindings/gnss/__init__.rst shared-bindings/gnss/ shared-bindings/gnss/__init__.rst shared-bindings/gnss/
shared-bindings/i2cperipheral/__init__.rst shared-bindings/i2cperipheral/ shared-bindings/i2cperipheral/__init__.rst shared-bindings/i2cperipheral/
shared-bindings/i2csecondary/__init__.rst shared-bindings/i2csecondary/ shared-bindings/i2csecondary/__init__.rst shared-bindings/i2csecondary/
@ -96,11 +90,11 @@ shared-bindings/microcontroller/Pin.rst shared-bindings/microcontroller/#microco
shared-bindings/microcontroller/Processor.rst shared-bindings/microcontroller/#microcontroller.Processor shared-bindings/microcontroller/Processor.rst shared-bindings/microcontroller/#microcontroller.Processor
shared-bindings/microcontroller/RunMode.rst shared-bindings/microcontroller/#microcontroller.RunMode shared-bindings/microcontroller/RunMode.rst shared-bindings/microcontroller/#microcontroller.RunMode
shared-bindings/microcontroller/__init__.rst shared-bindings/microcontroller/ shared-bindings/microcontroller/__init__.rst shared-bindings/microcontroller/
shared-bindings/multiterminal/__init__.rst shared-bindings/multiterminal/
shared-bindings/neopixel_write/__init__.rst shared-bindings/neopixel_write/ shared-bindings/neopixel_write/__init__.rst shared-bindings/neopixel_write/
shared-bindings/network/__init__.rst shared-bindings/network/ shared-bindings/network/__init__.rst shared-bindings/network/
shared-bindings/nvm/ByteArray.rst shared-bindings/nvm/#nvm.ByteArray shared-bindings/nvm/ByteArray.rst shared-bindings/nvm/#nvm.ByteArray
shared-bindings/nvm/__init__.rst shared-bindings/nvm/ shared-bindings/nvm/__init__.rst shared-bindings/nvm/
shared-bindings/onewireio/OneWire.rst shared-bindings/onewireio/#onewireio.OneWire
shared-bindings/os/__init__.rst shared-bindings/os/ shared-bindings/os/__init__.rst shared-bindings/os/
shared-bindings/protomatter/__init__.rst shared-bindings/protomatter/ shared-bindings/protomatter/__init__.rst shared-bindings/protomatter/
shared-bindings/ps2io/Ps2.rst shared-bindings/ps2io/#ps2io.Ps2 shared-bindings/ps2io/Ps2.rst shared-bindings/ps2io/#ps2io.Ps2

View File

@ -32,7 +32,7 @@ from concurrent.futures import ThreadPoolExecutor
SUPPORTED_PORTS = ['atmel-samd', 'broadcom', 'cxd56', 'espressif', 'litex', 'mimxrt10xx', 'nrf', 'raspberrypi', 'stm'] SUPPORTED_PORTS = ['atmel-samd', 'broadcom', 'cxd56', 'espressif', 'litex', 'mimxrt10xx', 'nrf', 'raspberrypi', 'stm']
aliases_by_board = { ALIASES_BY_BOARD = {
"circuitplayground_express": [ "circuitplayground_express": [
"circuitplayground_express_4h", "circuitplayground_express_4h",
"circuitplayground_express_digikey_pycon2019", "circuitplayground_express_digikey_pycon2019",
@ -40,10 +40,9 @@ aliases_by_board = {
"pybadge": ["edgebadge"], "pybadge": ["edgebadge"],
"pyportal": ["pyportal_pynt"], "pyportal": ["pyportal_pynt"],
"gemma_m0": ["gemma_m0_pycon2018"], "gemma_m0": ["gemma_m0_pycon2018"],
"pewpew10": ["pewpew13"],
} }
aliases_brand_names = { ALIASES_BRAND_NAMES = {
"circuitplayground_express_4h": "circuitplayground_express_4h":
"Adafruit Circuit Playground Express 4-H", "Adafruit Circuit Playground Express 4-H",
"circuitplayground_express_digikey_pycon2019": "circuitplayground_express_digikey_pycon2019":
@ -54,19 +53,27 @@ aliases_brand_names = {
"Adafruit PyPortal Pynt", "Adafruit PyPortal Pynt",
"gemma_m0_pycon2018": "gemma_m0_pycon2018":
"Adafruit Gemma M0 PyCon 2018", "Adafruit Gemma M0 PyCon 2018",
"pewpew13":
"PewPew 13",
} }
additional_modules = { ADDITIONAL_MODULES = {
"fontio": "CIRCUITPY_DISPLAYIO", "_asyncio": "MICROPY_PY_UASYNCIO",
"terminalio": "CIRCUITPY_DISPLAYIO",
"adafruit_bus_device": "CIRCUITPY_BUSDEVICE", "adafruit_bus_device": "CIRCUITPY_BUSDEVICE",
"adafruit_pixelbuf": "CIRCUITPY_PIXELBUF", "adafruit_pixelbuf": "CIRCUITPY_PIXELBUF",
"array": "CIRCUITPY_ARRAY",
# always available, so depend on something that's always 1.
"builtins": "CIRCUITPY",
"collections": "CIRCUITPY_COLLECTIONS",
"fontio": "CIRCUITPY_DISPLAYIO",
"io": "CIRCUITPY_IO",
"select": "MICROPY_PY_USELECT_SELECT",
"terminalio": "CIRCUITPY_DISPLAYIO",
"sys": "CIRCUITPY_SYS",
"usb": "CIRCUITPY_USB_HOST", "usb": "CIRCUITPY_USB_HOST",
} }
frozen_excludes = ["examples", "docs", "tests", "utils", "conf.py", "setup.py"] MODULES_NOT_IN_SHARED_BINDINGS = ["_asyncio", "array", "binascii", "builtins", "collections", "errno", "json", "re", "select", "sys", "ulab"]
FROZEN_EXCLUDES = ["examples", "docs", "tests", "utils", "conf.py", "setup.py"]
"""Files and dirs at the root of a frozen directory that should be ignored. """Files and dirs at the root of a frozen directory that should be ignored.
This is the same list as in the preprocess_frozen_modules script.""" This is the same list as in the preprocess_frozen_modules script."""
@ -74,7 +81,7 @@ repository_urls = {}
"""Cache of repository URLs for frozen modules.""" """Cache of repository URLs for frozen modules."""
def get_circuitpython_root_dir(): def get_circuitpython_root_dir():
""" The path to the root './circuitpython' directory """ The path to the root './circuitpython' directory.
""" """
file_path = pathlib.Path(__file__).resolve() file_path = pathlib.Path(__file__).resolve()
root_dir = file_path.parent.parent root_dir = file_path.parent.parent
@ -82,10 +89,38 @@ def get_circuitpython_root_dir():
return root_dir return root_dir
def get_shared_bindings(): def get_shared_bindings():
""" Get a list of modules in shared-bindings based on folder names """ Get a list of modules in shared-bindings based on folder names.
""" """
shared_bindings_dir = get_circuitpython_root_dir() / "shared-bindings" shared_bindings_dir = get_circuitpython_root_dir() / "shared-bindings"
return [item.name for item in shared_bindings_dir.iterdir()] + ["binascii", "errno", "json", "re", "ulab"] return [item.name for item in shared_bindings_dir.iterdir()] + MODULES_NOT_IN_SHARED_BINDINGS
def get_board_mapping():
"""
Compiles the list of boards from the directories, with aliases and mapping
to the port.
"""
boards = {}
for port in SUPPORTED_PORTS:
board_path = os.path.join("../ports", port, "boards")
for board_path in os.scandir(board_path):
if board_path.is_dir():
board_files = os.listdir(board_path.path)
board_id = board_path.name
aliases = ALIASES_BY_BOARD.get(board_path.name, [])
boards[board_id] = {
"port": port,
"download_count": 0,
"aliases": aliases,
}
for alias in aliases:
boards[alias] = {
"port": port,
"download_count": 0,
"alias": True,
"aliases": [],
}
return boards
def read_mpconfig(): def read_mpconfig():
@ -112,8 +147,8 @@ def build_module_map():
full_build = False full_build = False
for module in modules: for module in modules:
full_name = module full_name = module
if module in additional_modules: if module in ADDITIONAL_MODULES:
search_identifier = additional_modules[module] search_identifier = ADDITIONAL_MODULES[module]
else: else:
search_identifier = 'CIRCUITPY_'+module.lstrip("_").upper() search_identifier = 'CIRCUITPY_'+module.lstrip("_").upper()
re_pattern = f"{re.escape(search_identifier)}\s*\??=\s*(.+)" re_pattern = f"{re.escape(search_identifier)}\s*\??=\s*(.+)"
@ -204,27 +239,33 @@ def get_repository_url(directory):
repository_urls[directory] = path repository_urls[directory] = path
return path return path
def frozen_modules_from_dirs(frozen_mpy_dirs): def frozen_modules_from_dirs(frozen_mpy_dirs, withurl):
""" """
Go through the list of frozen directories and extract the python modules. Go through the list of frozen directories and extract the python modules.
Paths are of the type: Paths are of the type:
$(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground $(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground
$(TOP)/frozen/circuitpython-stage/meowbit $(TOP)/frozen/circuitpython-stage/meowbit
Python modules are at the root of the path, and are python files or directories Python modules are at the root of the path, and are python files or directories
containing python files. Except the ones in the frozen_excludes list. containing python files. Except the ones in the FROZEN_EXCLUDES list.
""" """
frozen_modules = [] frozen_modules = []
for frozen_path in filter(lambda x: x, frozen_mpy_dirs.split(" ")): for frozen_path in filter(lambda x: x, frozen_mpy_dirs.split(" ")):
source_dir = get_circuitpython_root_dir() / frozen_path[7:] source_dir = get_circuitpython_root_dir() / frozen_path[7:]
url_repository = get_repository_url(source_dir) url_repository = get_repository_url(source_dir)
for sub in source_dir.glob("*"): for sub in source_dir.glob("*"):
if sub.name in frozen_excludes: if sub.name in FROZEN_EXCLUDES:
continue continue
if sub.name.endswith(".py"): if sub.name.endswith(".py"):
frozen_modules.append((sub.name[:-3], url_repository)) if withurl:
frozen_modules.append((sub.name[:-3], url_repository))
else:
frozen_modules.append(sub.name[:-3])
continue continue
if next(sub.glob("**/*.py"), None): # tests if not empty if next(sub.glob("**/*.py"), None): # tests if not empty
frozen_modules.append((sub.name, url_repository)) if withurl:
frozen_modules.append((sub.name, url_repository))
else:
frozen_modules.append(sub.name)
return frozen_modules return frozen_modules
def lookup_setting(settings, key, default=''): def lookup_setting(settings, key, default=''):
@ -244,7 +285,7 @@ def all_ports_all_boards(ports=SUPPORTED_PORTS):
continue continue
yield (port, entry) yield (port, entry)
def support_matrix_by_board(use_branded_name=True): def support_matrix_by_board(use_branded_name=True, withurl=True):
""" Compiles a list of the available core modules available for each """ Compiles a list of the available core modules available for each
board. board.
""" """
@ -272,29 +313,49 @@ def support_matrix_by_board(use_branded_name=True):
board_modules.append(base[module]['name']) board_modules.append(base[module]['name'])
board_modules.sort() board_modules.sort()
if "CIRCUITPY_BUILD_EXTENSIONS" in settings:
board_extensions = [
extension.strip() for extension in
settings["CIRCUITPY_BUILD_EXTENSIONS"].split(",")
]
else:
raise OSError(f"Board extensions undefined: {board_name}.")
frozen_modules = [] frozen_modules = []
if "FROZEN_MPY_DIRS" in settings: if "FROZEN_MPY_DIRS" in settings:
frozen_modules = frozen_modules_from_dirs(settings["FROZEN_MPY_DIRS"]) frozen_modules = frozen_modules_from_dirs(settings["FROZEN_MPY_DIRS"], withurl)
if frozen_modules: if frozen_modules:
frozen_modules.sort() frozen_modules.sort()
# generate alias boards too # generate alias boards too
board_matrix = [(board_name, (board_modules, frozen_modules))] board_matrix = [(
if entry.name in aliases_by_board: board_name, {
for alias in aliases_by_board[entry.name]: "modules": board_modules,
"frozen_libraries": frozen_modules,
"extensions": board_extensions,
}
)]
if entry.name in ALIASES_BY_BOARD:
for alias in ALIASES_BY_BOARD[entry.name]:
if use_branded_name: if use_branded_name:
if alias in aliases_brand_names: if alias in ALIASES_BRAND_NAMES:
alias = aliases_brand_names[alias] alias = ALIASES_BRAND_NAMES[alias]
else: else:
alias = alias.replace("_"," ").title() alias = alias.replace("_"," ").title()
board_matrix.append( (alias, (board_modules, frozen_modules)) ) board_matrix.append((
alias, {
"modules": board_modules,
"frozen_libraries": frozen_modules,
"extensions": board_extensions,
},
))
return board_matrix # this is now a list of (board,modules) return board_matrix # this is now a list of (board,modules)
executor = ThreadPoolExecutor(max_workers=os.cpu_count()) executor = ThreadPoolExecutor(max_workers=os.cpu_count())
mapped_exec = executor.map(support_matrix, all_ports_all_boards()) mapped_exec = executor.map(support_matrix, all_ports_all_boards())
# flatmap with comprehensions # flatmap with comprehensions
boards = dict(sorted([board for matrix in mapped_exec for board in matrix])) boards = dict(sorted([board for matrix in mapped_exec for board in matrix], key=lambda x: x[0]))
return boards return boards

430
docs/workflows.md Normal file
View File

@ -0,0 +1,430 @@
# Workflows
Workflows are the process used to 1) manipulate files on the CircuitPython device and 2) interact
with the serial connection to CircuitPython. The serial connection is usually used to access the
REPL.
Starting with CircuitPython 3.x we moved to a USB-only workflow. Prior to that, we used the serial
connection alone to do the whole workflow. In CircuitPython 7.x, a BLE workflow was added with the
advantage of working with mobile devices. CircuitPython 8.x added a web workflow that works over the
local network (usually Wi-Fi) and a web browser. Other clients can also use the Web REST API. Boards
should clearly document which workflows are supported.
Code for workflows lives in `supervisor/shared`.
The workflow APIs are documented here.
## USB
These USB interfaces are enabled by default on boards with USB support. They are usable once the
device has been plugged into a host.
### CIRCUITPY drive
CircuitPython exposes a standard mass storage (MSC) interface to enable file manipulation over a
standard interface. This interface works underneath the file system at the block level so using it
excludes other types of workflows from manipulating the file system at the same time.
### CDC serial
CircuitPython exposes one CDC USB interface for CircuitPython serial. This is a standard serial
USB interface.
TODO: Document how it designates itself from the user CDC.
Setting baudrate 1200 and disconnecting will reboot into a bootloader. (Used by Arduino to trigger
a reset into bootloader.)
## BLE
The BLE workflow is enabled for nRF boards. By default, to prevent malicious access, it is disabled.
To connect to the BLE workflow, press the reset button while the status led blinks blue quickly
after the safe mode blinks. The board will restart and broadcast the file transfer service UUID
(`0xfebb`) along with the board's [Creation IDs](https://github.com/creationid/creators). This
public broadcast is done at a lower transmit level so the devices must be closer. On connection, the
device will need to pair and bond. Once bonded, the device will broadcast whenever disconnected
using a rotating key rather than a static one. Non-bonded devices won't be able to resolve it. After
connection, the central device can discover two default services. One for file transfer and one for
CircuitPython specifically that includes serial characteristics.
To change the default BLE advertising name without (or before) running user code, the desired name
can be put in the `/.env` file. The key is `CIRCUITPY_BLE_NAME`. It's limited to approximately
30 characters depending on the port's settings and will be truncated if longer.
### File Transfer API
CircuitPython uses [an open File Transfer API](https://github.com/adafruit/Adafruit_CircuitPython_BLE_File_Transfer)
to enable file system access.
### CircuitPython Service
The base UUID for the CircuitPython service is `ADAFXXXX-4369-7263-7569-7450794686e`. The `XXXX` is
replaced by the four specific digits below. The service itself is `0001`.
#### TX - `0002` / RX - `0003`
These characteristic work just like the Nordic Uart Service (NUS) but have different UUIDs to prevent
conflicts with user created NUS services.
#### Version - `0100`
Read-only characteristic that returns the UTF-8 encoded version string.
## Web
The web workflow is depends on adding Wi-Fi credentials into the `/.env` file. The keys are
`CIRCUITPY_WIFI_SSID` and `CIRCUITPY_WIFI_PASSWORD`. Once these are defined, CircuitPython will
automatically connect to the network and start the webserver used for the workflow. The webserver
is on port 80 unless overridden by `CIRCUITPY_WEB_API_PORT`. It also enables MDNS.
Here is an example `/.env`:
```bash
# To auto-connect to Wi-Fi
CIRCUITPY_WIFI_SSID='scottswifi'
CIRCUITPY_WIFI_PASSWORD='secretpassword'
# To enable modifying files from the web. Change this too!
# Leave the User field blank in the browser.
CIRCUITPY_WEB_API_PASSWORD='passw0rd'
CIRCUITPY_WEB_API_PORT=80
```
MDNS is used to resolve [`circuitpython.local`](http://circuitpython.local) to a device specific
hostname of the form `cpy-XXXXXX.local`. The `XXXXXX` is based on network MAC address. The device
also provides the MDNS service with service type `_circuitpython` and protocol `_tcp`.
### HTTP
The web server is HTTP 1.1 and may use chunked responses so that it doesn't need to precompute
content length.
The API generally consists of an HTTP method such as GET or PUT and a path. Requests and responses
also have headers. Responses will contain a status code and status text such as `404 Not Found`.
This API tries to use standard status codes to encode the status of the various operations. The
[Mozilla Developer Network HTTP docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP)
are a great reference.
#### Examples
The examples use `curl`, a common command line program for issuing HTTP requests. The examples below
use `circuitpython.local` as the easiest way to work. If you have multiple active devices, you'll
want to use the specific `cpy-XXXXXX.local` version.
The examples also use `passw0rd` as the password placeholder. Replace it with your password before
running the example.
### `/`
The root welcome page links to the file system page and also displays other CircuitPython devices
found using MDNS service discovery. This allows web browsers to find other devices from one. (All
devices will respond to `circuitpython.local` so the device redirected to may vary.)
### CORS
The web server will allow requests from `cpy-XXXXXX.local`, `127.0.0.1`, the device's IP and
`code.circuitpython.org`. (`circuitpython.local` requests will be redirected to `cpy-XXXXXX.local`.)
### File REST API
All file system related APIs are protected by HTTP basic authentication. It is *NOT* secure but will
hopefully prevent some griefing in shared settings. The password is sent unencrypted so do not reuse
a password with something important. The user field is left blank.
The password is taken from `/.env` with the key `CIRCUITPY_WEB_API_PASSWORD`. If this is unset, the
server will respond with `403 Forbidden`. When a password is set, but not provided in a request, it
will respond `401 Unauthorized`.
#### `/fs/`
The `/fs/` page will respond with a directory browsing HTML once authenticated. This page is always
gzipped. If the `Accept: application/json` header is provided, then the JSON representation of the
root will be returned.
##### OPTIONS
When requested with the `OPTIONS` method, the server will respond with CORS related headers. Most
aren't needed for API use. They are there for the web browser.
* `Access-Control-Allow-Methods` - Varies with USB state. `GET, OPTIONS` when USB is active. `GET, OPTIONS, PUT, DELETE, MOVE` otherwise.
Example:
```sh
curl -v -u :passw0rd -X OPTIONS -L --location-trusted http://circuitpython.local/fs/
```
#### `/fs/<directory path>/`
Directory paths must end with a /. Otherwise, the path is assumed to be a file.
##### GET
Returns a JSON representation of the directory.
* `200 OK` - Directory exists and JSON returned
* `401 Unauthorized` - Incorrect password
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
* `404 Not Found` - Missing directory
Returns information about each file in the directory:
* `name` - File name. No trailing `/` on directory names
* `directory` - `true` when a directory. `false` otherwise
* `modified_ns` - File modification time in nanoseconds since January 1st, 1970. May not use full resolution
* `file_size` - File size in bytes. `0` for directories
Example:
```sh
curl -v -u :passw0rd -H "Accept: application/json" -L --location-trusted http://circuitpython.local/fs/lib/hello/
```
```json
[
{
"name": "world.txt",
"directory": false,
"modified_ns": 946934328000000000,
"file_size": 12
}
]
```
##### PUT
Tries to make a directory at the given path. Request body is ignored. The custom `X-Timestamp`
header can provide a timestamp in milliseconds since January 1st, 1970 (to match JavaScript's file
time resolution) used for the directories modification time. The RTC time will used otherwise.
Returns:
* `204 No Content` - Directory exists
* `201 Created` - Directory created
* `401 Unauthorized` - Incorrect password
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
* `409 Conflict` - USB is active and preventing file system modification
* `404 Not Found` - Missing parent directory
* `500 Server Error` - Other, unhandled error
Example:
```sh
curl -v -u :passw0rd -X PUT -L --location-trusted http://circuitpython.local/fs/lib/hello/world/
```
##### Move
Moves the directory at the given path to ``X-Destination``. Also known as rename.
The custom `X-Destination` header stores the destination path of the directory.
* `201 Created` - Directory renamed
* `401 Unauthorized` - Incorrect password
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
* `404 Not Found` - Source directory not found or destination path is missing
* `409 Conflict` - USB is active and preventing file system modification
* `412 Precondition Failed` - The destination path is already in use
Example:
```sh
curl -v -u :passw0rd -X MOVE -H "X-Destination: /fs/lib/hello2/" -L --location-trusted http://circuitpython.local/fs/lib/hello/
```
##### DELETE
Deletes the directory and all of its contents.
* `204 No Content` - Directory and its contents deleted
* `401 Unauthorized` - Incorrect password
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
* `404 Not Found` - No directory
* `409 Conflict` - USB is active and preventing file system modification
Example:
```sh
curl -v -u :passw0rd -X DELETE -L --location-trusted http://circuitpython.local/fs/lib/hello2/world/
```
#### `/fs/<file path>`
##### PUT
Stores the provided content to the file path.
The custom `X-Timestamp` header can provide a timestamp in milliseconds since January 1st, 1970
(to match JavaScript's file time resolution) used for the directories modification time. The RTC
time will used otherwise.
Returns:
* `201 Created` - File created and saved
* `204 No Content` - File existed and overwritten
* `401 Unauthorized` - Incorrect password
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
* `404 Not Found` - Missing parent directory
* `409 Conflict` - USB is active and preventing file system modification
* `413 Payload Too Large` - `Expect` header not sent and file is too large
* `417 Expectation Failed` - `Expect` header sent and file is too large
* `500 Server Error` - Other, unhandled error
If the client sends the `Expect` header, the server will reply with `100 Continue` when ok.
Example:
```sh
echo "Hello world" >> test.txt
curl -v -u :passw0rd -T test.txt -L --location-trusted http://circuitpython.local/fs/lib/hello/world.txt
```
##### GET
Returns the raw file contents. `Content-Type` will be set based on extension:
* `text/plain` - `.py`, `.txt`
* `text/javascript` - `.js`
* `text/html` - `.html`
* `application/json` - `.json`
* `application/octet-stream` - Everything else
Will return:
* `200 OK` - File exists and file returned
* `401 Unauthorized` - Incorrect password
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
* `404 Not Found` - Missing file
Example:
```sh
curl -v -u :passw0rd -L --location-trusted http://circuitpython.local/fs/lib/hello/world.txt
```
##### Move
Moves the file at the given path to the ``X-Destination``. Also known as rename.
The custom `X-Destination` header stores the destination path of the file.
* `201 Created` - File renamed
* `401 Unauthorized` - Incorrect password
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
* `404 Not Found` - Source file not found or destination path is missing
* `409 Conflict` - USB is active and preventing file system modification
* `412 Precondition Failed` - The destination path is already in use
Example:
```sh
curl -v -u :passw0rd -X MOVE -H "X-Destination: /fs/lib/hello/world2.txt" -L --location-trusted http://circuitpython.local/fs/lib/hello/world.txt
```
##### DELETE
Deletes the file.
* `204 No Content` - File existed and deleted
* `401 Unauthorized` - Incorrect password
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
* `404 Not Found` - File not found
* `409 Conflict` - USB is active and preventing file system modification
Example:
```sh
curl -v -u :passw0rd -X DELETE -L --location-trusted http://circuitpython.local/fs/lib/hello/world2.txt
```
### `/cp/`
`/cp/` serves basic info about the CircuitPython device and others discovered through MDNS. It is
not protected by basic auth in case the device is someone elses.
Only `GET` requests are supported and will return `405 Method Not Allowed` otherwise.
#### `/cp/devices.json`
Returns information about other devices found on the network using MDNS.
* `total`: Total MDNS response count. May be more than in `devices` if internal limits were hit.
* `devices`: List of discovered devices.
* `hostname`: MDNS hostname
* `instance_name`: MDNS instance name. Defaults to human readable board name.
* `port`: Port of CircuitPython Web API
* `ip`: IP address
Example:
```sh
curl -v -L http://circuitpython.local/cp/devices.json
```
```json
{
"total": 1,
"devices": [
{
"hostname": "cpy-951032",
"instance_name": "Adafruit Feather ESP32-S2 TFT",
"port": 80,
"ip": "192.168.1.235"
}
]
}
```
#### `/cp/serial/`
Serves a basic serial terminal program when a `GET` request is received without the
`Upgrade: websocket` header. Otherwise the socket is upgraded to a WebSocket. See WebSockets below for more detail.
This is an authenticated endpoint in both modes.
#### `/cp/version.json`
Returns information about the device.
* `web_api_version`: Always `1`. This versions the rest of the API and new versions may not be backwards compatible.
* `version`: CircuitPython build version.
* `build_date`: CircuitPython build date.
* `board_name`: Human readable name of the board.
* `mcu_name`: Human readable name of the microcontroller.
* `board_id`: Board id used in code and on circuitpython.org.
* `creator_id`: Creator ID for the board.
* `creation_id`: Creation ID for the board, set by the creator.
* `hostname`: MDNS hostname.
* `port`: Port of CircuitPython Web Service.
* `ip`: IP address of the device.
Example:
```sh
curl -v -L http://circuitpython.local/cp/version.json
```
```json
{
"web_api_version": 1,
"version": "8.0.0-alpha.1-20-ge1d4518a9-dirty",
"build_date": "2022-06-24",
"board_name": "ESP32-S3-USB-OTG-N8",
"mcu_name": "ESP32S3",
"board_id": "espressif_esp32s3_usb_otg_n8",
"creator_id": 12346,
"creation_id": 28683,
"hostname": "cpy-f57ce8",
"port": 80,
"ip": "192.168.1.94"
}
```
#### `/code/`
The `/code/` page returns a small static html page that will pull in and load the full code editor from
[code.circuitpython.org](https://code.circuitpython.org) for a full code editor experience. Because most
of the resources reside online instead of the device, an active internet connection is required.
### Static files
* `/favicon.ico` - Blinka
* `/directory.js` - JavaScript for `/fs/`
* `/welcome.js` - JavaScript for `/`
### WebSocket
The CircuitPython serial interactions are available over a WebSocket. A WebSocket begins as a
special HTTP request that gets upgraded to a WebSocket. Authentication happens before upgrading.
WebSockets are *not* bare sockets once upgraded. Instead they have their own framing format for data.
CircuitPython can handle PING and CLOSE opcodes. All others are treated as TEXT. Data to
CircuitPython is expected to be masked UTF-8, as the spec requires. Data from CircuitPython to the
client is unmasked. It is also unbuffered so the client will get a variety of frame sizes.
Only one WebSocket at a time is supported.

View File

@ -33,6 +33,8 @@
#include "shared-bindings/supervisor/__init__.h" #include "shared-bindings/supervisor/__init__.h"
#endif #endif
#include "supervisor/shared/translate/translate.h"
#if MICROPY_PY_UASYNCIO #if MICROPY_PY_UASYNCIO
// Used when task cannot be guaranteed to be non-NULL. // Used when task cannot be guaranteed to be non-NULL.

View File

@ -11,6 +11,8 @@
#include "py/runtime.h" #include "py/runtime.h"
#include "py/binary.h" #include "py/binary.h"
#include "supervisor/shared/translate/translate.h"
static void check_not_unicode(const mp_obj_t arg) { static void check_not_unicode(const mp_obj_t arg) {
#if MICROPY_CPYTHON_COMPAT #if MICROPY_CPYTHON_COMPAT
if (mp_obj_is_str(arg)) { if (mp_obj_is_str(arg)) {

View File

@ -11,7 +11,7 @@
#include "py/objtuple.h" #include "py/objtuple.h"
#include "py/binary.h" #include "py/binary.h"
#include "supervisor/shared/translate.h" #include "supervisor/shared/translate/translate.h"
#if MICROPY_PY_UCTYPES #if MICROPY_PY_UCTYPES

View File

@ -8,7 +8,7 @@
#include "py/runtime.h" #include "py/runtime.h"
#include "supervisor/shared/translate.h" #include "supervisor/shared/translate/translate.h"
#if MICROPY_PY_UHASHLIB #if MICROPY_PY_UHASHLIB

View File

@ -6,7 +6,7 @@
#include "py/objlist.h" #include "py/objlist.h"
#include "py/runtime.h" #include "py/runtime.h"
#include "supervisor/shared/translate.h" #include "supervisor/shared/translate/translate.h"
#if MICROPY_PY_UHEAPQ #if MICROPY_PY_UHEAPQ

View File

@ -13,7 +13,7 @@
#include "py/runtime.h" #include "py/runtime.h"
#include "py/stream.h" #include "py/stream.h"
#include "supervisor/shared/translate.h" #include "supervisor/shared/translate/translate.h"
#if MICROPY_PY_UJSON #if MICROPY_PY_UJSON

View File

@ -10,7 +10,7 @@
#include "py/runtime.h" #include "py/runtime.h"
#include "py/smallint.h" #include "py/smallint.h"
#include "supervisor/shared/translate.h" #include "supervisor/shared/translate/translate.h"
#if MICROPY_PY_UTIMEQ #if MICROPY_PY_UTIMEQ

View File

@ -10,7 +10,7 @@
#include "py/stream.h" #include "py/stream.h"
#include "py/mperrno.h" #include "py/mperrno.h"
#include "supervisor/shared/translate.h" #include "supervisor/shared/translate/translate.h"
#if MICROPY_PY_UZLIB #if MICROPY_PY_UZLIB

@ -1 +1 @@
Subproject commit 5d01882c41dbc4115bc94f0b61c093d5a6b812b6 Subproject commit 57de23c1fb434ba99aaafe1d00bd77d5cdf5d66b

View File

@ -20,7 +20,7 @@
#include "extmod/vfs_fat.h" #include "extmod/vfs_fat.h"
#include "shared/timeutils/timeutils.h" #include "shared/timeutils/timeutils.h"
#include "supervisor/filesystem.h" #include "supervisor/filesystem.h"
#include "supervisor/shared/translate.h" #include "supervisor/shared/translate/translate.h"
#if FF_MAX_SS == FF_MIN_SS #if FF_MAX_SS == FF_MIN_SS
#define SECSIZE(fs) (FF_MIN_SS) #define SECSIZE(fs) (FF_MIN_SS)
@ -30,6 +30,11 @@
#define mp_obj_fat_vfs_t fs_user_mount_t #define mp_obj_fat_vfs_t fs_user_mount_t
// Factoring this common call saves about 90 bytes.
STATIC NORETURN void mp_raise_OSError_fresult(FRESULT res) {
mp_raise_OSError(fresult_to_errno_table[res]);
}
STATIC mp_import_stat_t fat_vfs_import_stat(void *vfs_in, const char *path) { STATIC mp_import_stat_t fat_vfs_import_stat(void *vfs_in, const char *path) {
fs_user_mount_t *vfs = vfs_in; fs_user_mount_t *vfs = vfs_in;
FILINFO fno; FILINFO fno;
@ -64,7 +69,7 @@ STATIC mp_obj_t fat_vfs_make_new(const mp_obj_type_t *type, size_t n_args, size_
// don't error out if no filesystem, to let mkfs()/mount() create one if wanted // don't error out if no filesystem, to let mkfs()/mount() create one if wanted
vfs->blockdev.flags |= MP_BLOCKDEV_FLAG_NO_FILESYSTEM; vfs->blockdev.flags |= MP_BLOCKDEV_FLAG_NO_FILESYSTEM;
} else if (res != FR_OK) { } else if (res != FR_OK) {
mp_raise_OSError(fresult_to_errno_table[res]); mp_raise_OSError_fresult(res);
} }
return MP_OBJ_FROM_PTR(vfs); return MP_OBJ_FROM_PTR(vfs);
@ -97,7 +102,7 @@ STATIC mp_obj_t fat_vfs_mkfs(mp_obj_t bdev_in) {
res = f_mkfs(&vfs->fatfs, FM_FAT32, 0, working_buf, sizeof(working_buf)); res = f_mkfs(&vfs->fatfs, FM_FAT32, 0, working_buf, sizeof(working_buf));
} }
if (res != FR_OK) { if (res != FR_OK) {
mp_raise_OSError(fresult_to_errno_table[res]); mp_raise_OSError_fresult(res);
} }
return mp_const_none; return mp_const_none;
@ -172,7 +177,7 @@ STATIC mp_obj_t fat_vfs_ilistdir_func(size_t n_args, const mp_obj_t *args) {
iter->is_str = is_str_type; iter->is_str = is_str_type;
FRESULT res = f_opendir(&self->fatfs, &iter->dir, path); FRESULT res = f_opendir(&self->fatfs, &iter->dir, path);
if (res != FR_OK) { if (res != FR_OK) {
mp_raise_OSError(fresult_to_errno_table[res]); mp_raise_OSError_fresult(res);
} }
return MP_OBJ_FROM_PTR(iter); return MP_OBJ_FROM_PTR(iter);
@ -188,7 +193,7 @@ STATIC mp_obj_t fat_vfs_remove_internal(mp_obj_t vfs_in, mp_obj_t path_in, mp_in
FRESULT res = f_stat(&self->fatfs, path, &fno); FRESULT res = f_stat(&self->fatfs, path, &fno);
if (res != FR_OK) { if (res != FR_OK) {
mp_raise_OSError(fresult_to_errno_table[res]); mp_raise_OSError_fresult(res);
} }
// check if path is a file or directory // check if path is a file or directory
@ -196,7 +201,7 @@ STATIC mp_obj_t fat_vfs_remove_internal(mp_obj_t vfs_in, mp_obj_t path_in, mp_in
res = f_unlink(&self->fatfs, path); res = f_unlink(&self->fatfs, path);
if (res != FR_OK) { if (res != FR_OK) {
mp_raise_OSError(fresult_to_errno_table[res]); mp_raise_OSError_fresult(res);
} }
return mp_const_none; return mp_const_none;
} else { } else {
@ -226,7 +231,7 @@ STATIC mp_obj_t fat_vfs_rename(mp_obj_t vfs_in, mp_obj_t path_in, mp_obj_t path_
FILINFO fno; FILINFO fno;
FRESULT res = f_stat(&self->fatfs, old_path, &fno); FRESULT res = f_stat(&self->fatfs, old_path, &fno);
if (res != FR_OK) { if (res != FR_OK) {
mp_raise_OSError(fresult_to_errno_table[res]); mp_raise_OSError_fresult(res);
} }
if ((fno.fattrib & AM_DIR) != 0 && if ((fno.fattrib & AM_DIR) != 0 &&
strlen(new_path) > strlen(old_path) && strlen(new_path) > strlen(old_path) &&
@ -245,7 +250,7 @@ STATIC mp_obj_t fat_vfs_rename(mp_obj_t vfs_in, mp_obj_t path_in, mp_obj_t path_
if (res == FR_OK) { if (res == FR_OK) {
return mp_const_none; return mp_const_none;
} else { } else {
mp_raise_OSError(fresult_to_errno_table[res]); mp_raise_OSError_fresult(res);
} }
} }
@ -259,7 +264,7 @@ STATIC mp_obj_t fat_vfs_mkdir(mp_obj_t vfs_in, mp_obj_t path_o) {
if (res == FR_OK) { if (res == FR_OK) {
return mp_const_none; return mp_const_none;
} else { } else {
mp_raise_OSError(fresult_to_errno_table[res]); mp_raise_OSError_fresult(res);
} }
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_mkdir_obj, fat_vfs_mkdir); STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_mkdir_obj, fat_vfs_mkdir);
@ -273,7 +278,7 @@ STATIC mp_obj_t fat_vfs_chdir(mp_obj_t vfs_in, mp_obj_t path_in) {
FRESULT res = f_chdir(&self->fatfs, path); FRESULT res = f_chdir(&self->fatfs, path);
if (res != FR_OK) { if (res != FR_OK) {
mp_raise_OSError(fresult_to_errno_table[res]); mp_raise_OSError_fresult(res);
} }
return mp_const_none; return mp_const_none;
@ -286,7 +291,7 @@ STATIC mp_obj_t fat_vfs_getcwd(mp_obj_t vfs_in) {
char buf[MICROPY_ALLOC_PATH_MAX + 1]; char buf[MICROPY_ALLOC_PATH_MAX + 1];
FRESULT res = f_getcwd(&self->fatfs, buf, sizeof(buf)); FRESULT res = f_getcwd(&self->fatfs, buf, sizeof(buf));
if (res != FR_OK) { if (res != FR_OK) {
mp_raise_OSError(fresult_to_errno_table[res]); mp_raise_OSError_fresult(res);
} }
return mp_obj_new_str(buf, strlen(buf)); return mp_obj_new_str(buf, strlen(buf));
} }
@ -307,7 +312,7 @@ STATIC mp_obj_t fat_vfs_stat(mp_obj_t vfs_in, mp_obj_t path_in) {
} else { } else {
FRESULT res = f_stat(&self->fatfs, path, &fno); FRESULT res = f_stat(&self->fatfs, path, &fno);
if (res != FR_OK) { if (res != FR_OK) {
mp_raise_OSError(fresult_to_errno_table[res]); mp_raise_OSError_fresult(res);
} }
} }
@ -357,7 +362,7 @@ STATIC mp_obj_t fat_vfs_statvfs(mp_obj_t vfs_in, mp_obj_t path_in) {
FATFS *fatfs = &self->fatfs; FATFS *fatfs = &self->fatfs;
FRESULT res = f_getfree(fatfs, &nclst); FRESULT res = f_getfree(fatfs, &nclst);
if (FR_OK != res) { if (FR_OK != res) {
mp_raise_OSError(fresult_to_errno_table[res]); mp_raise_OSError_fresult(res);
} }
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL)); mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL));
@ -395,7 +400,7 @@ STATIC mp_obj_t vfs_fat_mount(mp_obj_t self_in, mp_obj_t readonly, mp_obj_t mkfs
res = f_mkfs(&self->fatfs, FM_FAT | FM_SFD, 0, working_buf, sizeof(working_buf)); res = f_mkfs(&self->fatfs, FM_FAT | FM_SFD, 0, working_buf, sizeof(working_buf));
} }
if (res != FR_OK) { if (res != FR_OK) {
mp_raise_OSError(fresult_to_errno_table[res]); mp_raise_OSError_fresult(res);
} }
self->blockdev.flags &= ~MP_BLOCKDEV_FLAG_NO_FILESYSTEM; self->blockdev.flags &= ~MP_BLOCKDEV_FLAG_NO_FILESYSTEM;
@ -416,7 +421,7 @@ STATIC mp_obj_t vfs_fat_getlabel(mp_obj_t self_in) {
char working_buf[12]; char working_buf[12];
FRESULT res = f_getlabel(&self->fatfs, working_buf, NULL); FRESULT res = f_getlabel(&self->fatfs, working_buf, NULL);
if (res != FR_OK) { if (res != FR_OK) {
mp_raise_OSError(fresult_to_errno_table[res]); mp_raise_OSError_fresult(res);
} }
return mp_obj_new_str(working_buf, strlen(working_buf)); return mp_obj_new_str(working_buf, strlen(working_buf));
} }
@ -431,7 +436,7 @@ STATIC mp_obj_t vfs_fat_setlabel(mp_obj_t self_in, mp_obj_t label_in) {
if (res == FR_WRITE_PROTECTED) { if (res == FR_WRITE_PROTECTED) {
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Read-only filesystem")); mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Read-only filesystem"));
} }
mp_raise_OSError(fresult_to_errno_table[res]); mp_raise_OSError_fresult(res);
} }
return mp_const_none; return mp_const_none;
} }

View File

@ -182,7 +182,7 @@ STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_ar
} }
if (rwxa_count != 1 || plus_count > 1 || bt_count > 1 || bad_mode) { if (rwxa_count != 1 || plus_count > 1 || bt_count > 1 || bad_mode) {
mp_raise_ValueError(translate("Invalid mode")); mp_arg_error_invalid(MP_QSTR_mode);
} }
assert(vfs != NULL); assert(vfs != NULL);

View File

@ -8,7 +8,7 @@
#include "py/runtime.h" #include "py/runtime.h"
#include "py/stream.h" #include "py/stream.h"
#include "extmod/vfs_posix.h" #include "extmod/vfs_posix.h"
#include "supervisor/shared/translate.h" #include "supervisor/shared/translate/translate.h"
#if (defined(MICROPY_VFS_POSIX) && MICROPY_VFS_POSIX) || (defined(MICROPY_VFS_POSIX_FILE) && MICROPY_VFS_POSIX_FILE) #if (defined(MICROPY_VFS_POSIX) && MICROPY_VFS_POSIX) || (defined(MICROPY_VFS_POSIX_FILE) && MICROPY_VFS_POSIX_FILE)

@ -1 +1 @@
Subproject commit 9bd48820928afad549832fe9b4ae497b224007f0 Subproject commit ba05423ed9aae09ce293603b519a4ac644ef0dab

@ -1 +1 @@
Subproject commit 13c529288e9431541fe58cf7992d4f53f7ca3b76 Subproject commit 4fd499e39720f8ce970cceeb97c2a85c485f7335

@ -1 +1 @@
Subproject commit 258bb62c58e545c38749b8a66f5872035b2384cb Subproject commit b06b47037aed97475b1676b104d1f4b05c3f5e86

@ -1 +1 @@
Subproject commit b96f0d279481446017ca1cc1ff4abf1f5a10346f Subproject commit 9ace770b048be9ab0da4a154af279dbb643bbdb0

@ -1 +1 @@
Subproject commit f82d3ef195256aa71d274a34ea25f760d7e651d1 Subproject commit 47f848f13f75d2f62d16407edaaf6dd0ec1fc3cc

@ -1 +1 @@
Subproject commit 938f6bb335ba5e4c56a8062c591ff9f3c18c4297 Subproject commit a37c7cc83685f2ff84a171a519207567a75d0947

@ -1 +1 @@
Subproject commit 8e7e111a9ff39d3f4311caa7babeb451422c759f Subproject commit 4a4619a524918f2705c05ca4959385937afa9a7c

@ -1 +1 @@
Subproject commit df2449815433e05ea0f89c19518ccde7a10a2faa Subproject commit 726270f5103d9d94810eb8b52041b7521afafc5c

@ -1 +1 @@
Subproject commit 2fad6f2f98c0df135e2306d32af18bb2796b852c Subproject commit 288a4f553d2f616331b5a042568c97b5bb0e44a7

@ -1 +1 @@
Subproject commit de3276cc08ba13901d1f69060ff7501c1699bc4d Subproject commit 41f06c33ef7a029210416ac61319698f5768e83e

@ -1 +1 @@
Subproject commit a90579e1e1e1c973e6ba8f6cf8e914d77fc8f0f2 Subproject commit d645fc2aded3606e5b0c17689e9f29e7e56bb612

@ -1 +1 @@
Subproject commit ddd26eb4abcd3c10ae5dd33b1345d10d58707995 Subproject commit ee6bfcf9e676eb435c8890db37f07719984a60a1

@ -1 +1 @@
Subproject commit f6cdec74b64112016c459abe4a5d31a3b34caeb3 Subproject commit 8eedf860beca0d32219189b72ea6fc8eea7e66db

@ -1 +1 @@
Subproject commit a77f0f9c2e8f64568bbb68254d0134fbc7b5a8af Subproject commit 3d7d404a1cafc02f6c3391b100157490132e5c5f

@ -1 +1 @@
Subproject commit 2fddabcaf0df1763111ed9dbf9e2d4cdb5b0434e Subproject commit 93c7e0ed55e7ed011908ac9a1c0f8228f0f4323b

@ -1 +1 @@
Subproject commit 1e478b1530b3be81bd84f13620d0a23502d377f1 Subproject commit 992b601e2469f30e95ec35c9859b4aa2cd917504

@ -0,0 +1 @@
Subproject commit 794488d1de3d17d1a08887c4a651cfac2c5a1524

@ -1 +1 @@
Subproject commit a9cf0cde77c185c6bbc79a3b6d77dd024a9683d2 Subproject commit 1919916dcf57e0879832b9c274c5fb77712d7775

@ -1 +1 @@
Subproject commit acc4bdd73fdceb74d75cd5a1f261ae157ee32613 Subproject commit 18eaddb96aa6599901ef2ff0e140e89a2de8c5d0

@ -1 +1 @@
Subproject commit 3d1aab0daf63c3b4476f73cba39cf5da49e1e4aa Subproject commit c8e82b96c68041a11a52f3053d0d2733ae2d1a49

@ -1 +1 @@
Subproject commit 3d871907f0187c627277382f184209f5520703a6 Subproject commit b6891e734183f978e7b3d0a363140e98635c0a04

@ -1 +1 @@
Subproject commit 207953aac033d40728b5f8dd7fd73d90facbca5c Subproject commit 31c819f377cf71f61cfb84eae159f1f948980db7

@ -1 +1 @@
Subproject commit 36d4a31010461e47f265553ebd764c69d38a254c Subproject commit 1064fdee5a1421f528af452be5e45ae95ef2b89a

@ -1 +1 @@
Subproject commit bcfaae874fbae294ce04549d55b96d6b41603944 Subproject commit 7eeea1aaf6bb5fa0deb080a1dc1aa3cd103f9aad

@ -1 +1 @@
Subproject commit 011acd627fc24342c397fc640b204a798f7b69dd Subproject commit cad34af5267aca3665fdaf1ea5a0eee921d13f06

@ -1 +1 @@
Subproject commit c58defd70947531c5a9c37ddcb569f240567a78b Subproject commit a815f364badc0dac3fe49e7d8206d00ce95894e1

@ -1 +1 @@
Subproject commit 2d8310f19d1bdce817df13e807b409b5b057fc21 Subproject commit df4c73a5e719f17fae0309e811ff17627cd0f268

@ -1 +1 @@
Subproject commit 49ab415d6b601c99979262f9e91c21dcb3a927a7 Subproject commit f611d5e31c9735a3c3ac43185e35dcd5f659e3aa

@ -1 +1 @@
Subproject commit 2e6b3f9feeacc678402454f7d3416b04a9a93e17 Subproject commit a5d56f3e4866c8dbb343e03500355a42c46e557a

@ -1 +1 @@
Subproject commit da02c76d4c802cd5abac73a5f274243b05e8cb35 Subproject commit c59df6b8c3d8006c290b63e95996e49e8e7124c0

@ -1 +1 @@
Subproject commit 850c3dc512f7feae1eaad20bdc1c5e4c63c92f08 Subproject commit 9ff56ce53f05e23ff678965ba54af89b24b1199a

@ -1 +1 @@
Subproject commit 272d225365eed46916390cf1f393dd08bc00b7d4 Subproject commit 0a8fcbfc92060eb298ea52d5e88587b37347a0be

@ -1 +1 @@
Subproject commit fad0f89e760829a76f553ef8459f61001597a846 Subproject commit dc605bb22914d77d80c5342cbb4c10f773aede95

@ -1 +1 @@
Subproject commit e86f258e43591ce4a04661277e77e9fdf6fec27e Subproject commit 43a4f15d604919d6e143e975a85abf7b96a4061d

@ -0,0 +1 @@
Subproject commit 5436a0f27f33b364035ce499c020b274d77a25b7

@ -0,0 +1 @@
Subproject commit 3e8c50eb2230de7b8a20dedac33334b5dbdee21e

@ -1 +1 @@
Subproject commit 3aaf72165bc6ba10bf5219716c8654651649f87b Subproject commit 6234787515e2f0ece40b6408722ff0b42824038e

@ -1 +1 @@
Subproject commit 3bdd335452ff14a53d1e840de043e3159cb3b829 Subproject commit 4124dfbdaadce1966f457d7d6c6984e9832999bf

@ -0,0 +1 @@
Subproject commit 6e8eedb1475e2b91f8dea7bceebb20e44d70b171

@ -0,0 +1 @@
Subproject commit 53f15602460329f69fef95498e6b8293aebb513a

1
frozen/mixgo_cp_lib Submodule

@ -0,0 +1 @@
Subproject commit d5e3e809d7aa938b233b49526c55bfd2e314272c

@ -1 +1 @@
Subproject commit 837f3e5f16accae5b3677954921b5ddd517f0799 Subproject commit 6452f2a78f32cf3b5d07e699f26d25e9c4d10d09

1
lib/mbedtls Submodule

@ -0,0 +1 @@
Subproject commit 1bc2c9cb8b8fe4659bd94b8ebba5a4c02029b7fa

View File

@ -0,0 +1,42 @@
MBEDTLS Error Strings for MicroPython
=====================================
This directory contains source code and tools to rework the Mbedtls error strings for
micropython to use less space. In short, instead of storing and printing something like
"SSL - Our own certificate(s) is/are too large to send in an SSL message" it prints
the name of the error #define, which would be "MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE" in
this case, and only stores `SSL_CERTIFICATE_TOO_LARGE` in flash. The exact Mbedtls error
defines are used because they're easy to search for to find more detailed information.
Mbedtls defines a specific format for error value #defines and
includes a Perl script to gather all `MBEDTLS_ERR` defines from includes files together with
english error text. From that the Perl script generates `mbedtls_strerror()`. The files in this
directory modify this process to produce a more space efficient error lookup table with
shorter error strings.
The files are as follows:
- `generate_errors.diff` - diff for original mbedtls perl script
- `error.fmt` - modified code template for MicroPython
- `mp_mbedtls_errors.c` - source file with `mbedtls_strerror` this is built using the include
files in `../mbedtls`
- `do-mp.sh` - shell script to produce `mp_mbedtls_errors.c`
- `tester.c` - simple C main to test `mp_mbedtls_errors.c` locally on a dev box
- `do-test.sh` - shell script to produce `mp_mbedtls_errors.c` and compile the `tester` app
- `do-esp32.sh` - shell script to produce `esp32_mbedtls_errors.c` -- see below
In order not to store multiple copies of `mbedtls_errors.c`
([https://github.com/micropython/micropython/pull/5819#discussion_r445528006](see))
it is assumed that all ports use the same version of mbedtls with the same error #defines.
This is true as of MP v1.13, and ESP-IDF versions 3.3.2 and 4.0.1. If anything changes in the
future the `do-esp32.sh` script can be used to generate an esp32-specific version.
### How-to
- To build MicroPython all that is needed is to include the `mp_mbedtls_errors.c` into the build
(the Makefiles do this automatically). Note that Perl is not needed for routine MicroPython
builds.
- When a new version of Mbedtls is pulled-in the `do-mp.sh` script should be run to
re-generate `mp_mbedtls_errors.c`.
- The `tester` app should be run if changes to the string handling in `error.fmt` are made:
it tests that there is not an off-by-one error in the string copying/appending, etc.
- To include `mbedtls_strerror` error strings define `MBEDTLS_ERROR_C` in the build.

7
lib/mbedtls_errors/do-esp32.sh Executable file
View File

@ -0,0 +1,7 @@
#! /bin/bash -e
# Generate esp32_mbedtls_errors.c for use in the Esp32 port, with the ESP-IDF version of mbedtls
# The IDF_PATH env var must be set to the top-level dir of ESPIDF
echo "IDF_PATH=$IDF_PATH"
MBEDTLS=$IDF_PATH/components/mbedtls/mbedtls
patch -o esp32_generate_errors.pl $MBEDTLS/scripts/generate_errors.pl <generate_errors.diff
perl ./esp32_generate_errors.pl $MBEDTLS/include/mbedtls . esp32_mbedtls_errors.c

4
lib/mbedtls_errors/do-mp.sh Executable file
View File

@ -0,0 +1,4 @@
#! /bin/bash -e
# Generate mp_mbedtls_errors.c for inclusion in ports that use $MPY/lib/mbedtls
patch -o mp_generate_errors.pl ../mbedtls/scripts/generate_errors.pl <generate_errors.diff
perl ./mp_generate_errors.pl ../mbedtls/include/mbedtls . mp_mbedtls_errors.c

4
lib/mbedtls_errors/do-test.sh Executable file
View File

@ -0,0 +1,4 @@
#! /bin/bash -e
# Generate mp_mbedtls_errors.c and build the tester app
./do-mp.sh
cc -o tester -I../mbedtls/include/ mp_mbedtls_errors.c tester.c

View File

@ -0,0 +1,165 @@
/*
* Error message information
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY)
#include "mbedtls/error.h"
#include <string.h>
#endif
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#define mbedtls_snprintf snprintf
#define mbedtls_time_t time_t
#endif
#if defined(MBEDTLS_ERROR_C)
#include <stdio.h>
HEADER_INCLUDED
// Error code table type
struct ssl_errs {
int16_t errnum;
const char *errstr;
};
// Table of high level error codes
static const struct ssl_errs mbedtls_high_level_error_tab[] = {
// BEGIN generated code
HIGH_LEVEL_CODE_CHECKS
// END generated code
};
static const struct ssl_errs mbedtls_low_level_error_tab[] = {
// Low level error codes
//
// BEGIN generated code
LOW_LEVEL_CODE_CHECKS
// END generated code
};
static const char *mbedtls_err_prefix = "MBEDTLS_ERR_";
#define MBEDTLS_ERR_PREFIX_LEN ( sizeof("MBEDTLS_ERR_")-1 )
// copy error text into buffer, ensure null termination, return strlen of result
static size_t mbedtls_err_to_str(int err, const struct ssl_errs tab[], int tab_len, char *buf, size_t buflen) {
if (buflen == 0) return 0;
// prefix for all error names
strncpy(buf, mbedtls_err_prefix, buflen);
if (buflen <= MBEDTLS_ERR_PREFIX_LEN+1) {
buf[buflen-1] = 0;
return buflen-1;
}
// append error name from table
for (int i = 0; i < tab_len; i++) {
if (tab[i].errnum == err) {
strncpy(buf+MBEDTLS_ERR_PREFIX_LEN, tab[i].errstr, buflen-MBEDTLS_ERR_PREFIX_LEN);
buf[buflen-1] = 0;
return strlen(buf);
}
}
mbedtls_snprintf(buf+MBEDTLS_ERR_PREFIX_LEN, buflen-MBEDTLS_ERR_PREFIX_LEN, "UNKNOWN (0x%04X)",
err);
return strlen(buf);
}
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
void mbedtls_strerror(int ret, char *buf, size_t buflen) {
int use_ret;
if (buflen == 0) return;
buf[buflen-1] = 0;
if (ret < 0) ret = -ret;
//
// High-level error codes
//
uint8_t got_hl = (ret & 0xFF80) != 0;
if (got_hl) {
use_ret = ret & 0xFF80;
// special case
#if defined(MBEDTLS_SSL_TLS_C)
if (use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE)) {
strncpy(buf, "MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE", buflen);
buf[buflen-1] = 0;
return;
}
#endif
size_t len = mbedtls_err_to_str(use_ret, mbedtls_high_level_error_tab,
ARRAY_SIZE(mbedtls_high_level_error_tab), buf, buflen);
buf += len;
buflen -= len;
if (buflen == 0) return;
}
//
// Low-level error codes
//
use_ret = ret & ~0xFF80;
if (use_ret == 0) return;
// If high level code is present, make a concatenation between both error strings.
if (got_hl) {
if (buflen < 2) return;
*buf++ = '+';
buflen--;
}
mbedtls_err_to_str(use_ret, mbedtls_low_level_error_tab,
ARRAY_SIZE(mbedtls_low_level_error_tab), buf, buflen);
}
#else /* MBEDTLS_ERROR_C */
#if defined(MBEDTLS_ERROR_STRERROR_DUMMY)
/*
* Provide an non-function in case MBEDTLS_ERROR_C is not defined
*/
void mbedtls_strerror( int ret, char *buf, size_t buflen )
{
((void) ret);
if( buflen > 0 )
buf[0] = '\0';
}
#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */
#endif /* MBEDTLS_ERROR_C */

View File

@ -0,0 +1,22 @@
--- generate_errors_orig.pl 2020-06-20 08:40:38.819060379 -0700
+++ generate_errors.pl 2020-06-20 08:47:26.511163591 -0700
@@ -162,16 +162,12 @@
if ($error_name eq "MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE")
{
- ${$code_check} .= "${white_space}if( use_ret == -($error_name) )\n".
- "${white_space}\{\n".
- "${white_space} mbedtls_snprintf( buf, buflen, \"$module_name - $description\" );\n".
- "${white_space} return;\n".
- "${white_space}}\n"
+ # no-op, this case is hard-coded in error.fmt
}
else
{
- ${$code_check} .= "${white_space}if( use_ret == -($error_name) )\n".
- "${white_space} mbedtls_snprintf( buf, buflen, \"$module_name - $description\" );\n"
+ my $error_text = $error_name =~ s/^MBEDTLS_ERR_//r;
+ ${$code_check} .= "${white_space}{ -($error_name), \"$error_text\" },\n"
}
};

View File

@ -0,0 +1,705 @@
/*
* Error message information
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY)
#include "mbedtls/error.h"
#include <string.h>
#endif
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#define mbedtls_snprintf snprintf
#define mbedtls_time_t time_t
#endif
#if defined(MBEDTLS_ERROR_C)
#include <stdio.h>
#if defined(MBEDTLS_AES_C)
#include "mbedtls/aes.h"
#endif
#if defined(MBEDTLS_ARC4_C)
#include "mbedtls/arc4.h"
#endif
#if defined(MBEDTLS_ARIA_C)
#include "mbedtls/aria.h"
#endif
#if defined(MBEDTLS_BASE64_C)
#include "mbedtls/base64.h"
#endif
#if defined(MBEDTLS_BIGNUM_C)
#include "mbedtls/bignum.h"
#endif
#if defined(MBEDTLS_BLOWFISH_C)
#include "mbedtls/blowfish.h"
#endif
#if defined(MBEDTLS_CAMELLIA_C)
#include "mbedtls/camellia.h"
#endif
#if defined(MBEDTLS_CCM_C)
#include "mbedtls/ccm.h"
#endif
#if defined(MBEDTLS_CHACHA20_C)
#include "mbedtls/chacha20.h"
#endif
#if defined(MBEDTLS_CHACHAPOLY_C)
#include "mbedtls/chachapoly.h"
#endif
#if defined(MBEDTLS_CIPHER_C)
#include "mbedtls/cipher.h"
#endif
#if defined(MBEDTLS_CMAC_C)
#include "mbedtls/cmac.h"
#endif
#if defined(MBEDTLS_CTR_DRBG_C)
#include "mbedtls/ctr_drbg.h"
#endif
#if defined(MBEDTLS_DES_C)
#include "mbedtls/des.h"
#endif
#if defined(MBEDTLS_DHM_C)
#include "mbedtls/dhm.h"
#endif
#if defined(MBEDTLS_ECP_C)
#include "mbedtls/ecp.h"
#endif
#if defined(MBEDTLS_ENTROPY_C)
#include "mbedtls/entropy.h"
#endif
#if defined(MBEDTLS_GCM_C)
#include "mbedtls/gcm.h"
#endif
#if defined(MBEDTLS_HKDF_C)
#include "mbedtls/hkdf.h"
#endif
#if defined(MBEDTLS_HMAC_DRBG_C)
#include "mbedtls/hmac_drbg.h"
#endif
#if defined(MBEDTLS_MD_C)
#include "mbedtls/md.h"
#endif
#if defined(MBEDTLS_MD2_C)
#include "mbedtls/md2.h"
#endif
#if defined(MBEDTLS_MD4_C)
#include "mbedtls/md4.h"
#endif
#if defined(MBEDTLS_MD5_C)
#include "mbedtls/md5.h"
#endif
#if defined(MBEDTLS_NET_C)
#include "mbedtls/net_sockets.h"
#endif
#if defined(MBEDTLS_OID_C)
#include "mbedtls/oid.h"
#endif
#if defined(MBEDTLS_PADLOCK_C)
#include "mbedtls/padlock.h"
#endif
#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
#include "mbedtls/pem.h"
#endif
#if defined(MBEDTLS_PK_C)
#include "mbedtls/pk.h"
#endif
#if defined(MBEDTLS_PKCS12_C)
#include "mbedtls/pkcs12.h"
#endif
#if defined(MBEDTLS_PKCS5_C)
#include "mbedtls/pkcs5.h"
#endif
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#endif
#if defined(MBEDTLS_POLY1305_C)
#include "mbedtls/poly1305.h"
#endif
#if defined(MBEDTLS_RIPEMD160_C)
#include "mbedtls/ripemd160.h"
#endif
#if defined(MBEDTLS_RSA_C)
#include "mbedtls/rsa.h"
#endif
#if defined(MBEDTLS_SHA1_C)
#include "mbedtls/sha1.h"
#endif
#if defined(MBEDTLS_SHA256_C)
#include "mbedtls/sha256.h"
#endif
#if defined(MBEDTLS_SHA512_C)
#include "mbedtls/sha512.h"
#endif
#if defined(MBEDTLS_SSL_TLS_C)
#include "mbedtls/ssl.h"
#endif
#if defined(MBEDTLS_THREADING_C)
#include "mbedtls/threading.h"
#endif
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
#include "mbedtls/x509.h"
#endif
#if defined(MBEDTLS_XTEA_C)
#include "mbedtls/xtea.h"
#endif
// Error code table type
struct ssl_errs {
int16_t errnum;
const char *errstr;
};
// Table of high level error codes
static const struct ssl_errs mbedtls_high_level_error_tab[] = {
// BEGIN generated code
#if defined(MBEDTLS_CIPHER_C)
{ -(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE), "CIPHER_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA), "CIPHER_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_CIPHER_ALLOC_FAILED), "CIPHER_ALLOC_FAILED" },
{ -(MBEDTLS_ERR_CIPHER_INVALID_PADDING), "CIPHER_INVALID_PADDING" },
{ -(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED), "CIPHER_FULL_BLOCK_EXPECTED" },
{ -(MBEDTLS_ERR_CIPHER_AUTH_FAILED), "CIPHER_AUTH_FAILED" },
{ -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT), "CIPHER_INVALID_CONTEXT" },
{ -(MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED), "CIPHER_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_CIPHER_C */
#if defined(MBEDTLS_DHM_C)
{ -(MBEDTLS_ERR_DHM_BAD_INPUT_DATA), "DHM_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED), "DHM_READ_PARAMS_FAILED" },
{ -(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED), "DHM_MAKE_PARAMS_FAILED" },
{ -(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED), "DHM_READ_PUBLIC_FAILED" },
{ -(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED), "DHM_MAKE_PUBLIC_FAILED" },
{ -(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED), "DHM_CALC_SECRET_FAILED" },
{ -(MBEDTLS_ERR_DHM_INVALID_FORMAT), "DHM_INVALID_FORMAT" },
{ -(MBEDTLS_ERR_DHM_ALLOC_FAILED), "DHM_ALLOC_FAILED" },
{ -(MBEDTLS_ERR_DHM_FILE_IO_ERROR), "DHM_FILE_IO_ERROR" },
{ -(MBEDTLS_ERR_DHM_HW_ACCEL_FAILED), "DHM_HW_ACCEL_FAILED" },
{ -(MBEDTLS_ERR_DHM_SET_GROUP_FAILED), "DHM_SET_GROUP_FAILED" },
#endif /* MBEDTLS_DHM_C */
#if defined(MBEDTLS_ECP_C)
{ -(MBEDTLS_ERR_ECP_BAD_INPUT_DATA), "ECP_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL), "ECP_BUFFER_TOO_SMALL" },
{ -(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE), "ECP_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_ECP_VERIFY_FAILED), "ECP_VERIFY_FAILED" },
{ -(MBEDTLS_ERR_ECP_ALLOC_FAILED), "ECP_ALLOC_FAILED" },
{ -(MBEDTLS_ERR_ECP_RANDOM_FAILED), "ECP_RANDOM_FAILED" },
{ -(MBEDTLS_ERR_ECP_INVALID_KEY), "ECP_INVALID_KEY" },
{ -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH), "ECP_SIG_LEN_MISMATCH" },
{ -(MBEDTLS_ERR_ECP_HW_ACCEL_FAILED), "ECP_HW_ACCEL_FAILED" },
{ -(MBEDTLS_ERR_ECP_IN_PROGRESS), "ECP_IN_PROGRESS" },
#endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_MD_C)
{ -(MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE), "MD_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_MD_BAD_INPUT_DATA), "MD_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_MD_ALLOC_FAILED), "MD_ALLOC_FAILED" },
{ -(MBEDTLS_ERR_MD_FILE_IO_ERROR), "MD_FILE_IO_ERROR" },
{ -(MBEDTLS_ERR_MD_HW_ACCEL_FAILED), "MD_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_MD_C */
#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
{ -(MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT), "PEM_NO_HEADER_FOOTER_PRESENT" },
{ -(MBEDTLS_ERR_PEM_INVALID_DATA), "PEM_INVALID_DATA" },
{ -(MBEDTLS_ERR_PEM_ALLOC_FAILED), "PEM_ALLOC_FAILED" },
{ -(MBEDTLS_ERR_PEM_INVALID_ENC_IV), "PEM_INVALID_ENC_IV" },
{ -(MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG), "PEM_UNKNOWN_ENC_ALG" },
{ -(MBEDTLS_ERR_PEM_PASSWORD_REQUIRED), "PEM_PASSWORD_REQUIRED" },
{ -(MBEDTLS_ERR_PEM_PASSWORD_MISMATCH), "PEM_PASSWORD_MISMATCH" },
{ -(MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE), "PEM_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_PEM_BAD_INPUT_DATA), "PEM_BAD_INPUT_DATA" },
#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */
#if defined(MBEDTLS_PK_C)
{ -(MBEDTLS_ERR_PK_ALLOC_FAILED), "PK_ALLOC_FAILED" },
{ -(MBEDTLS_ERR_PK_TYPE_MISMATCH), "PK_TYPE_MISMATCH" },
{ -(MBEDTLS_ERR_PK_BAD_INPUT_DATA), "PK_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_PK_FILE_IO_ERROR), "PK_FILE_IO_ERROR" },
{ -(MBEDTLS_ERR_PK_KEY_INVALID_VERSION), "PK_KEY_INVALID_VERSION" },
{ -(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT), "PK_KEY_INVALID_FORMAT" },
{ -(MBEDTLS_ERR_PK_UNKNOWN_PK_ALG), "PK_UNKNOWN_PK_ALG" },
{ -(MBEDTLS_ERR_PK_PASSWORD_REQUIRED), "PK_PASSWORD_REQUIRED" },
{ -(MBEDTLS_ERR_PK_PASSWORD_MISMATCH), "PK_PASSWORD_MISMATCH" },
{ -(MBEDTLS_ERR_PK_INVALID_PUBKEY), "PK_INVALID_PUBKEY" },
{ -(MBEDTLS_ERR_PK_INVALID_ALG), "PK_INVALID_ALG" },
{ -(MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE), "PK_UNKNOWN_NAMED_CURVE" },
{ -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE), "PK_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH), "PK_SIG_LEN_MISMATCH" },
{ -(MBEDTLS_ERR_PK_HW_ACCEL_FAILED), "PK_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_PK_C */
#if defined(MBEDTLS_PKCS12_C)
{ -(MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA), "PKCS12_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE), "PKCS12_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT), "PKCS12_PBE_INVALID_FORMAT" },
{ -(MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH), "PKCS12_PASSWORD_MISMATCH" },
#endif /* MBEDTLS_PKCS12_C */
#if defined(MBEDTLS_PKCS5_C)
{ -(MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA), "PKCS5_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_PKCS5_INVALID_FORMAT), "PKCS5_INVALID_FORMAT" },
{ -(MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE), "PKCS5_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH), "PKCS5_PASSWORD_MISMATCH" },
#endif /* MBEDTLS_PKCS5_C */
#if defined(MBEDTLS_RSA_C)
{ -(MBEDTLS_ERR_RSA_BAD_INPUT_DATA), "RSA_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_RSA_INVALID_PADDING), "RSA_INVALID_PADDING" },
{ -(MBEDTLS_ERR_RSA_KEY_GEN_FAILED), "RSA_KEY_GEN_FAILED" },
{ -(MBEDTLS_ERR_RSA_KEY_CHECK_FAILED), "RSA_KEY_CHECK_FAILED" },
{ -(MBEDTLS_ERR_RSA_PUBLIC_FAILED), "RSA_PUBLIC_FAILED" },
{ -(MBEDTLS_ERR_RSA_PRIVATE_FAILED), "RSA_PRIVATE_FAILED" },
{ -(MBEDTLS_ERR_RSA_VERIFY_FAILED), "RSA_VERIFY_FAILED" },
{ -(MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE), "RSA_OUTPUT_TOO_LARGE" },
{ -(MBEDTLS_ERR_RSA_RNG_FAILED), "RSA_RNG_FAILED" },
{ -(MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION), "RSA_UNSUPPORTED_OPERATION" },
{ -(MBEDTLS_ERR_RSA_HW_ACCEL_FAILED), "RSA_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_SSL_TLS_C)
{ -(MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE), "SSL_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_SSL_BAD_INPUT_DATA), "SSL_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_SSL_INVALID_MAC), "SSL_INVALID_MAC" },
{ -(MBEDTLS_ERR_SSL_INVALID_RECORD), "SSL_INVALID_RECORD" },
{ -(MBEDTLS_ERR_SSL_CONN_EOF), "SSL_CONN_EOF" },
{ -(MBEDTLS_ERR_SSL_UNKNOWN_CIPHER), "SSL_UNKNOWN_CIPHER" },
{ -(MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN), "SSL_NO_CIPHER_CHOSEN" },
{ -(MBEDTLS_ERR_SSL_NO_RNG), "SSL_NO_RNG" },
{ -(MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE), "SSL_NO_CLIENT_CERTIFICATE" },
{ -(MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE), "SSL_CERTIFICATE_TOO_LARGE" },
{ -(MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED), "SSL_CERTIFICATE_REQUIRED" },
{ -(MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED), "SSL_PRIVATE_KEY_REQUIRED" },
{ -(MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED), "SSL_CA_CHAIN_REQUIRED" },
{ -(MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE), "SSL_UNEXPECTED_MESSAGE" },
{ -(MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED), "SSL_PEER_VERIFY_FAILED" },
{ -(MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY), "SSL_PEER_CLOSE_NOTIFY" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO), "SSL_BAD_HS_CLIENT_HELLO" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO), "SSL_BAD_HS_SERVER_HELLO" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE), "SSL_BAD_HS_CERTIFICATE" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST), "SSL_BAD_HS_CERTIFICATE_REQUEST" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE), "SSL_BAD_HS_SERVER_KEY_EXCHANGE" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE), "SSL_BAD_HS_SERVER_HELLO_DONE" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE), "SSL_BAD_HS_CLIENT_KEY_EXCHANGE" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP), "SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS), "SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY), "SSL_BAD_HS_CERTIFICATE_VERIFY" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC), "SSL_BAD_HS_CHANGE_CIPHER_SPEC" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_FINISHED), "SSL_BAD_HS_FINISHED" },
{ -(MBEDTLS_ERR_SSL_ALLOC_FAILED), "SSL_ALLOC_FAILED" },
{ -(MBEDTLS_ERR_SSL_HW_ACCEL_FAILED), "SSL_HW_ACCEL_FAILED" },
{ -(MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH), "SSL_HW_ACCEL_FALLTHROUGH" },
{ -(MBEDTLS_ERR_SSL_COMPRESSION_FAILED), "SSL_COMPRESSION_FAILED" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION), "SSL_BAD_HS_PROTOCOL_VERSION" },
{ -(MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET), "SSL_BAD_HS_NEW_SESSION_TICKET" },
{ -(MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED), "SSL_SESSION_TICKET_EXPIRED" },
{ -(MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH), "SSL_PK_TYPE_MISMATCH" },
{ -(MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY), "SSL_UNKNOWN_IDENTITY" },
{ -(MBEDTLS_ERR_SSL_INTERNAL_ERROR), "SSL_INTERNAL_ERROR" },
{ -(MBEDTLS_ERR_SSL_COUNTER_WRAPPING), "SSL_COUNTER_WRAPPING" },
{ -(MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO), "SSL_WAITING_SERVER_HELLO_RENEGO" },
{ -(MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED), "SSL_HELLO_VERIFY_REQUIRED" },
{ -(MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL), "SSL_BUFFER_TOO_SMALL" },
{ -(MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE), "SSL_NO_USABLE_CIPHERSUITE" },
{ -(MBEDTLS_ERR_SSL_WANT_READ), "SSL_WANT_READ" },
{ -(MBEDTLS_ERR_SSL_WANT_WRITE), "SSL_WANT_WRITE" },
{ -(MBEDTLS_ERR_SSL_TIMEOUT), "SSL_TIMEOUT" },
{ -(MBEDTLS_ERR_SSL_CLIENT_RECONNECT), "SSL_CLIENT_RECONNECT" },
{ -(MBEDTLS_ERR_SSL_UNEXPECTED_RECORD), "SSL_UNEXPECTED_RECORD" },
{ -(MBEDTLS_ERR_SSL_NON_FATAL), "SSL_NON_FATAL" },
{ -(MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH), "SSL_INVALID_VERIFY_HASH" },
{ -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING), "SSL_CONTINUE_PROCESSING" },
{ -(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS), "SSL_ASYNC_IN_PROGRESS" },
{ -(MBEDTLS_ERR_SSL_EARLY_MESSAGE), "SSL_EARLY_MESSAGE" },
{ -(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS), "SSL_CRYPTO_IN_PROGRESS" },
#endif /* MBEDTLS_SSL_TLS_C */
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
{ -(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE), "X509_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_X509_UNKNOWN_OID), "X509_UNKNOWN_OID" },
{ -(MBEDTLS_ERR_X509_INVALID_FORMAT), "X509_INVALID_FORMAT" },
{ -(MBEDTLS_ERR_X509_INVALID_VERSION), "X509_INVALID_VERSION" },
{ -(MBEDTLS_ERR_X509_INVALID_SERIAL), "X509_INVALID_SERIAL" },
{ -(MBEDTLS_ERR_X509_INVALID_ALG), "X509_INVALID_ALG" },
{ -(MBEDTLS_ERR_X509_INVALID_NAME), "X509_INVALID_NAME" },
{ -(MBEDTLS_ERR_X509_INVALID_DATE), "X509_INVALID_DATE" },
{ -(MBEDTLS_ERR_X509_INVALID_SIGNATURE), "X509_INVALID_SIGNATURE" },
{ -(MBEDTLS_ERR_X509_INVALID_EXTENSIONS), "X509_INVALID_EXTENSIONS" },
{ -(MBEDTLS_ERR_X509_UNKNOWN_VERSION), "X509_UNKNOWN_VERSION" },
{ -(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG), "X509_UNKNOWN_SIG_ALG" },
{ -(MBEDTLS_ERR_X509_SIG_MISMATCH), "X509_SIG_MISMATCH" },
{ -(MBEDTLS_ERR_X509_CERT_VERIFY_FAILED), "X509_CERT_VERIFY_FAILED" },
{ -(MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT), "X509_CERT_UNKNOWN_FORMAT" },
{ -(MBEDTLS_ERR_X509_BAD_INPUT_DATA), "X509_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_X509_ALLOC_FAILED), "X509_ALLOC_FAILED" },
{ -(MBEDTLS_ERR_X509_FILE_IO_ERROR), "X509_FILE_IO_ERROR" },
{ -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL), "X509_BUFFER_TOO_SMALL" },
{ -(MBEDTLS_ERR_X509_FATAL_ERROR), "X509_FATAL_ERROR" },
#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */
// END generated code
};
static const struct ssl_errs mbedtls_low_level_error_tab[] = {
// Low level error codes
//
// BEGIN generated code
#if defined(MBEDTLS_AES_C)
{ -(MBEDTLS_ERR_AES_INVALID_KEY_LENGTH), "AES_INVALID_KEY_LENGTH" },
{ -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH), "AES_INVALID_INPUT_LENGTH" },
{ -(MBEDTLS_ERR_AES_BAD_INPUT_DATA), "AES_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE), "AES_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_AES_HW_ACCEL_FAILED), "AES_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_AES_C */
#if defined(MBEDTLS_ARC4_C)
{ -(MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED), "ARC4_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_ARC4_C */
#if defined(MBEDTLS_ARIA_C)
{ -(MBEDTLS_ERR_ARIA_BAD_INPUT_DATA), "ARIA_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH), "ARIA_INVALID_INPUT_LENGTH" },
{ -(MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE), "ARIA_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED), "ARIA_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_ARIA_C */
#if defined(MBEDTLS_ASN1_PARSE_C)
{ -(MBEDTLS_ERR_ASN1_OUT_OF_DATA), "ASN1_OUT_OF_DATA" },
{ -(MBEDTLS_ERR_ASN1_UNEXPECTED_TAG), "ASN1_UNEXPECTED_TAG" },
{ -(MBEDTLS_ERR_ASN1_INVALID_LENGTH), "ASN1_INVALID_LENGTH" },
{ -(MBEDTLS_ERR_ASN1_LENGTH_MISMATCH), "ASN1_LENGTH_MISMATCH" },
{ -(MBEDTLS_ERR_ASN1_INVALID_DATA), "ASN1_INVALID_DATA" },
{ -(MBEDTLS_ERR_ASN1_ALLOC_FAILED), "ASN1_ALLOC_FAILED" },
{ -(MBEDTLS_ERR_ASN1_BUF_TOO_SMALL), "ASN1_BUF_TOO_SMALL" },
#endif /* MBEDTLS_ASN1_PARSE_C */
#if defined(MBEDTLS_BASE64_C)
{ -(MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL), "BASE64_BUFFER_TOO_SMALL" },
{ -(MBEDTLS_ERR_BASE64_INVALID_CHARACTER), "BASE64_INVALID_CHARACTER" },
#endif /* MBEDTLS_BASE64_C */
#if defined(MBEDTLS_BIGNUM_C)
{ -(MBEDTLS_ERR_MPI_FILE_IO_ERROR), "MPI_FILE_IO_ERROR" },
{ -(MBEDTLS_ERR_MPI_BAD_INPUT_DATA), "MPI_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_MPI_INVALID_CHARACTER), "MPI_INVALID_CHARACTER" },
{ -(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL), "MPI_BUFFER_TOO_SMALL" },
{ -(MBEDTLS_ERR_MPI_NEGATIVE_VALUE), "MPI_NEGATIVE_VALUE" },
{ -(MBEDTLS_ERR_MPI_DIVISION_BY_ZERO), "MPI_DIVISION_BY_ZERO" },
{ -(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE), "MPI_NOT_ACCEPTABLE" },
{ -(MBEDTLS_ERR_MPI_ALLOC_FAILED), "MPI_ALLOC_FAILED" },
#endif /* MBEDTLS_BIGNUM_C */
#if defined(MBEDTLS_BLOWFISH_C)
{ -(MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA), "BLOWFISH_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH), "BLOWFISH_INVALID_INPUT_LENGTH" },
{ -(MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED), "BLOWFISH_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_BLOWFISH_C */
#if defined(MBEDTLS_CAMELLIA_C)
{ -(MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA), "CAMELLIA_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH), "CAMELLIA_INVALID_INPUT_LENGTH" },
{ -(MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED), "CAMELLIA_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_CAMELLIA_C */
#if defined(MBEDTLS_CCM_C)
{ -(MBEDTLS_ERR_CCM_BAD_INPUT), "CCM_BAD_INPUT" },
{ -(MBEDTLS_ERR_CCM_AUTH_FAILED), "CCM_AUTH_FAILED" },
{ -(MBEDTLS_ERR_CCM_HW_ACCEL_FAILED), "CCM_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_CCM_C */
#if defined(MBEDTLS_CHACHA20_C)
{ -(MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA), "CHACHA20_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE), "CHACHA20_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED), "CHACHA20_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_CHACHA20_C */
#if defined(MBEDTLS_CHACHAPOLY_C)
{ -(MBEDTLS_ERR_CHACHAPOLY_BAD_STATE), "CHACHAPOLY_BAD_STATE" },
{ -(MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED), "CHACHAPOLY_AUTH_FAILED" },
#endif /* MBEDTLS_CHACHAPOLY_C */
#if defined(MBEDTLS_CMAC_C)
{ -(MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED), "CMAC_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_CMAC_C */
#if defined(MBEDTLS_CTR_DRBG_C)
{ -(MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED), "CTR_DRBG_ENTROPY_SOURCE_FAILED" },
{ -(MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG), "CTR_DRBG_REQUEST_TOO_BIG" },
{ -(MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG), "CTR_DRBG_INPUT_TOO_BIG" },
{ -(MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR), "CTR_DRBG_FILE_IO_ERROR" },
#endif /* MBEDTLS_CTR_DRBG_C */
#if defined(MBEDTLS_DES_C)
{ -(MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH), "DES_INVALID_INPUT_LENGTH" },
{ -(MBEDTLS_ERR_DES_HW_ACCEL_FAILED), "DES_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_DES_C */
#if defined(MBEDTLS_ENTROPY_C)
{ -(MBEDTLS_ERR_ENTROPY_SOURCE_FAILED), "ENTROPY_SOURCE_FAILED" },
{ -(MBEDTLS_ERR_ENTROPY_MAX_SOURCES), "ENTROPY_MAX_SOURCES" },
{ -(MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED), "ENTROPY_NO_SOURCES_DEFINED" },
{ -(MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE), "ENTROPY_NO_STRONG_SOURCE" },
{ -(MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR), "ENTROPY_FILE_IO_ERROR" },
#endif /* MBEDTLS_ENTROPY_C */
#if defined(MBEDTLS_GCM_C)
{ -(MBEDTLS_ERR_GCM_AUTH_FAILED), "GCM_AUTH_FAILED" },
{ -(MBEDTLS_ERR_GCM_HW_ACCEL_FAILED), "GCM_HW_ACCEL_FAILED" },
{ -(MBEDTLS_ERR_GCM_BAD_INPUT), "GCM_BAD_INPUT" },
#endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_HKDF_C)
{ -(MBEDTLS_ERR_HKDF_BAD_INPUT_DATA), "HKDF_BAD_INPUT_DATA" },
#endif /* MBEDTLS_HKDF_C */
#if defined(MBEDTLS_HMAC_DRBG_C)
{ -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG), "HMAC_DRBG_REQUEST_TOO_BIG" },
{ -(MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG), "HMAC_DRBG_INPUT_TOO_BIG" },
{ -(MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR), "HMAC_DRBG_FILE_IO_ERROR" },
{ -(MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED), "HMAC_DRBG_ENTROPY_SOURCE_FAILED" },
#endif /* MBEDTLS_HMAC_DRBG_C */
#if defined(MBEDTLS_MD2_C)
{ -(MBEDTLS_ERR_MD2_HW_ACCEL_FAILED), "MD2_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_MD2_C */
#if defined(MBEDTLS_MD4_C)
{ -(MBEDTLS_ERR_MD4_HW_ACCEL_FAILED), "MD4_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_MD4_C */
#if defined(MBEDTLS_MD5_C)
{ -(MBEDTLS_ERR_MD5_HW_ACCEL_FAILED), "MD5_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_MD5_C */
#if defined(MBEDTLS_NET_C)
{ -(MBEDTLS_ERR_NET_SOCKET_FAILED), "NET_SOCKET_FAILED" },
{ -(MBEDTLS_ERR_NET_CONNECT_FAILED), "NET_CONNECT_FAILED" },
{ -(MBEDTLS_ERR_NET_BIND_FAILED), "NET_BIND_FAILED" },
{ -(MBEDTLS_ERR_NET_LISTEN_FAILED), "NET_LISTEN_FAILED" },
{ -(MBEDTLS_ERR_NET_ACCEPT_FAILED), "NET_ACCEPT_FAILED" },
{ -(MBEDTLS_ERR_NET_RECV_FAILED), "NET_RECV_FAILED" },
{ -(MBEDTLS_ERR_NET_SEND_FAILED), "NET_SEND_FAILED" },
{ -(MBEDTLS_ERR_NET_CONN_RESET), "NET_CONN_RESET" },
{ -(MBEDTLS_ERR_NET_UNKNOWN_HOST), "NET_UNKNOWN_HOST" },
{ -(MBEDTLS_ERR_NET_BUFFER_TOO_SMALL), "NET_BUFFER_TOO_SMALL" },
{ -(MBEDTLS_ERR_NET_INVALID_CONTEXT), "NET_INVALID_CONTEXT" },
{ -(MBEDTLS_ERR_NET_POLL_FAILED), "NET_POLL_FAILED" },
{ -(MBEDTLS_ERR_NET_BAD_INPUT_DATA), "NET_BAD_INPUT_DATA" },
#endif /* MBEDTLS_NET_C */
#if defined(MBEDTLS_OID_C)
{ -(MBEDTLS_ERR_OID_NOT_FOUND), "OID_NOT_FOUND" },
{ -(MBEDTLS_ERR_OID_BUF_TOO_SMALL), "OID_BUF_TOO_SMALL" },
#endif /* MBEDTLS_OID_C */
#if defined(MBEDTLS_PADLOCK_C)
{ -(MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED), "PADLOCK_DATA_MISALIGNED" },
#endif /* MBEDTLS_PADLOCK_C */
#if defined(MBEDTLS_PLATFORM_C)
{ -(MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED), "PLATFORM_HW_ACCEL_FAILED" },
{ -(MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED), "PLATFORM_FEATURE_UNSUPPORTED" },
#endif /* MBEDTLS_PLATFORM_C */
#if defined(MBEDTLS_POLY1305_C)
{ -(MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA), "POLY1305_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE), "POLY1305_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED), "POLY1305_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_POLY1305_C */
#if defined(MBEDTLS_RIPEMD160_C)
{ -(MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED), "RIPEMD160_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_RIPEMD160_C */
#if defined(MBEDTLS_SHA1_C)
{ -(MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED), "SHA1_HW_ACCEL_FAILED" },
{ -(MBEDTLS_ERR_SHA1_BAD_INPUT_DATA), "SHA1_BAD_INPUT_DATA" },
#endif /* MBEDTLS_SHA1_C */
#if defined(MBEDTLS_SHA256_C)
{ -(MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED), "SHA256_HW_ACCEL_FAILED" },
{ -(MBEDTLS_ERR_SHA256_BAD_INPUT_DATA), "SHA256_BAD_INPUT_DATA" },
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C)
{ -(MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED), "SHA512_HW_ACCEL_FAILED" },
{ -(MBEDTLS_ERR_SHA512_BAD_INPUT_DATA), "SHA512_BAD_INPUT_DATA" },
#endif /* MBEDTLS_SHA512_C */
#if defined(MBEDTLS_THREADING_C)
{ -(MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE), "THREADING_FEATURE_UNAVAILABLE" },
{ -(MBEDTLS_ERR_THREADING_BAD_INPUT_DATA), "THREADING_BAD_INPUT_DATA" },
{ -(MBEDTLS_ERR_THREADING_MUTEX_ERROR), "THREADING_MUTEX_ERROR" },
#endif /* MBEDTLS_THREADING_C */
#if defined(MBEDTLS_XTEA_C)
{ -(MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH), "XTEA_INVALID_INPUT_LENGTH" },
{ -(MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED), "XTEA_HW_ACCEL_FAILED" },
#endif /* MBEDTLS_XTEA_C */
// END generated code
};
static const char *mbedtls_err_prefix = "MBEDTLS_ERR_";
#define MBEDTLS_ERR_PREFIX_LEN ( sizeof("MBEDTLS_ERR_")-1 )
// copy error text into buffer, ensure null termination, return strlen of result
static size_t mbedtls_err_to_str(int err, const struct ssl_errs tab[], int tab_len, char *buf, size_t buflen) {
if (buflen == 0) return 0;
// prefix for all error names
strncpy(buf, mbedtls_err_prefix, buflen);
if (buflen <= MBEDTLS_ERR_PREFIX_LEN+1) {
buf[buflen-1] = 0;
return buflen-1;
}
// append error name from table
for (int i = 0; i < tab_len; i++) {
if (tab[i].errnum == err) {
strncpy(buf+MBEDTLS_ERR_PREFIX_LEN, tab[i].errstr, buflen-MBEDTLS_ERR_PREFIX_LEN);
buf[buflen-1] = 0;
return strlen(buf);
}
}
mbedtls_snprintf(buf+MBEDTLS_ERR_PREFIX_LEN, buflen-MBEDTLS_ERR_PREFIX_LEN, "UNKNOWN (0x%04X)",
err);
return strlen(buf);
}
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
void mbedtls_strerror(int ret, char *buf, size_t buflen) {
int use_ret;
if (buflen == 0) return;
buf[buflen-1] = 0;
if (ret < 0) ret = -ret;
//
// High-level error codes
//
uint8_t got_hl = (ret & 0xFF80) != 0;
if (got_hl) {
use_ret = ret & 0xFF80;
// special case
#if defined(MBEDTLS_SSL_TLS_C)
if (use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE)) {
strncpy(buf, "MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE", buflen);
buf[buflen-1] = 0;
return;
}
#endif
size_t len = mbedtls_err_to_str(use_ret, mbedtls_high_level_error_tab,
ARRAY_SIZE(mbedtls_high_level_error_tab), buf, buflen);
buf += len;
buflen -= len;
if (buflen == 0) return;
}
//
// Low-level error codes
//
use_ret = ret & ~0xFF80;
if (use_ret == 0) return;
// If high level code is present, make a concatenation between both error strings.
if (got_hl) {
if (buflen < 2) return;
*buf++ = '+';
buflen--;
}
mbedtls_err_to_str(use_ret, mbedtls_low_level_error_tab,
ARRAY_SIZE(mbedtls_low_level_error_tab), buf, buflen);
}
#else /* MBEDTLS_ERROR_C */
#if defined(MBEDTLS_ERROR_STRERROR_DUMMY)
/*
* Provide an non-function in case MBEDTLS_ERROR_C is not defined
*/
void mbedtls_strerror( int ret, char *buf, size_t buflen )
{
((void) ret);
if( buflen > 0 )
buf[0] = '\0';
}
#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */
#endif /* MBEDTLS_ERROR_C */

View File

@ -0,0 +1,58 @@
#include "mbedtls/error.h"
#include <string.h>
#include <stdio.h>
// test_code checks that the provided code results in the provided error string for any size
// buffer. It calls mbedtls_strerror() to fill a buffer that is from 1 to 100 bytes in length
// and then checks that the buffer contents is OK and that a few guard bytes before and after
// the buffer were not overwritten.
int test_code(int code, char *str) {
char buf[100];
int ok = 1;
int res;
// test zero-length buffer
memset(buf, -3, 100);
mbedtls_strerror(code, buf + 4, 0);
for (int i = 0; i < 10; i++) {
if (buf[i] != -3) {
printf("Error: guard overwritten buflen=0 i=%d buf[i]=%d\n", i, buf[i]);
ok = 0;
}
}
// test
for (size_t buflen = 1; buflen < 90; buflen++) {
memset(buf, -3, 100);
mbedtls_strerror(code, buf + 4, buflen);
for (int i = 0; i < 4; i++) {
if (buf[i] != -3) {
printf("Error: pre-guard overwritten buflen=%d i=%d buf[i]=%d\n", buflen, i, buf[i]);
ok = 0;
}
}
for (int i = 4 + buflen; i < 100; i++) {
if (buf[i] != -3) {
printf("Error: post-guard overwritten buflen=%d i=%d buf[i]=%d\n", buflen, i, buf[i]);
ok = 0;
}
}
char exp[100];
strncpy(exp, str, buflen);
exp[buflen - 1] = 0;
if (strcmp(buf + 4, exp) != 0) {
printf("Error: expected %s, got %s\n", exp, buf);
ok = 0;
}
}
printf("Test %x -> %s is %s\n", code, str, ok?"OK":"*** BAD ***");
}
int main() {
test_code(0x7200, "MBEDTLS_ERR_SSL_INVALID_RECORD");
test_code(0x7780, "MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE");
test_code(0x0074, "MBEDTLS_ERR_SHA256_BAD_INPUT_DATA");
test_code(0x6600 | 0x0074, "MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH+MBEDTLS_ERR_SHA256_BAD_INPUT_DATA");
test_code(103, "MBEDTLS_ERR_UNKNOWN (0x0067)");
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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