Merge pull request #2 from adafruit/main

update fork
This commit is contained in:
ajs256 2021-04-25 12:36:53 -07:00 committed by GitHub
commit 453fd9234f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2456 changed files with 65241 additions and 49178 deletions

1
.gitattributes vendored
View file

@ -18,6 +18,7 @@
*.deb binary *.deb binary
*.zip binary *.zip binary
*.pdf binary *.pdf binary
*.wav binary
# These should also not be modified by git. # These should also not be modified by git.
tests/basics/string_cr_conversion.py -text tests/basics/string_cr_conversion.py -text

54
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View file

@ -0,0 +1,54 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: 'bug'
assignees: ''
---
<!-- Thanks! for testing out CircuitPython. Now that you have got a problem...
you can file a bug report for it. Feel free to modify the below format to better
suit your issue. :) -->
**Firmware**
<!-- Include the version of CircuitPython you're running. You can see it in the
`boot_out.txt` file, as well as in the REPL. -->
```python
Adafruit CircuitPython 6.2.0-beta.2 on 2021-03-01; Raspberry Pi Pico with rp2040
```
**Code/REPL**
<!-- Include your code that reproduces the bug here. Try to distill down to the
minimum possible to reproduce. -->
```python
import busio, bitbangio
i2c = bitbangio.I2C(board.GP1, board.GP0)
```
**Behavior**
<!-- What happens when you run the code above? Include any error messages. -->
```python
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TimeoutError: Clock stretch too long
```
**Description**
<!-- Optionally, describe the issue in more detail. Here are some examples: -->
- Error while using i2c...
- Only happens when...
- might be related to #4291...
**Additional Info**
<!-- Optionally, add any other information like hardware connection, scope output etc.
If you have already done some debugging, mention it here. -->

7
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View file

@ -0,0 +1,7 @@
contact_links:
- name: Adafruit Forum
url: https://forums.adafruit.com/
about: Official Adafruit technical support forum. Good for getting help on getting a project working.
- name: Adafruit Discord
url: https://adafru.it/discord
about: Unofficial chat with many helpful folks and normally prompt replies.

View file

@ -0,0 +1,11 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: 'enhancement'
assignees: ''
---
<!-- We are always adding new features and enhancements to CircuitPython 🚀
and would love ❤ to see what new challenge you have got for us... 🙂 -->

View file

@ -38,13 +38,11 @@ jobs:
sudo apt-get update sudo apt-get update
sudo apt-get install -y eatmydata sudo apt-get install -y eatmydata
sudo eatmydata apt-get install -y gettext librsvg2-bin mingw-w64 latexmk texlive-fonts-recommended texlive-latex-recommended texlive-latex-extra sudo eatmydata apt-get install -y gettext librsvg2-bin mingw-w64 latexmk texlive-fonts-recommended texlive-latex-recommended texlive-latex-extra
pip install requests sh click setuptools cpp-coveralls "Sphinx<4" sphinx-rtd-theme recommonmark sphinx-autoapi sphinxcontrib-svg2pdfconverter polib pyyaml astroid isort black awscli mypy pip install -r requirements-dev.txt
- name: Versions - name: Versions
run: | run: |
gcc --version gcc --version
python3 --version python3 --version
- name: Translations
run: make check-translate
- name: New boards check - name: New boards check
run: python3 -u ci_new_boards_check.py run: python3 -u ci_new_boards_check.py
working-directory: tools working-directory: tools
@ -81,6 +79,7 @@ jobs:
working-directory: tests working-directory: tests
- name: Print failure info - name: Print failure info
run: | run: |
shopt -s nullglob;
for exp in *.exp; for exp in *.exp;
do testbase=$(basename $exp .exp); do testbase=$(basename $exp .exp);
echo -e "\nFAILURE $testbase"; echo -e "\nFAILURE $testbase";
@ -133,15 +132,6 @@ jobs:
env: env:
GITHUB_CONTEXT: ${{ toJson(github) }} GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT" run: echo "$GITHUB_CONTEXT"
- name: Install dependencies
run: |
brew install gettext
echo >>$GITHUB_PATH /usr/local/opt/gettext/bin
- name: Versions
run: |
gcc --version
python3 --version
msgfmt --version
- uses: actions/checkout@v2.2.0 - uses: actions/checkout@v2.2.0
with: with:
submodules: true submodules: true
@ -151,6 +141,15 @@ jobs:
run: | run: |
git describe --dirty --tags git describe --dirty --tags
echo >>$GITHUB_ENV CP_VERSION=$(git describe --dirty --tags) echo >>$GITHUB_ENV CP_VERSION=$(git describe --dirty --tags)
- name: Install dependencies
run: |
brew install gettext
echo >>$GITHUB_PATH /usr/local/opt/gettext/bin
- name: Versions
run: |
gcc --version
python3 --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@v2
@ -178,7 +177,14 @@ jobs:
- "ADM_B_NRF52840_1" - "ADM_B_NRF52840_1"
- "TG-Watch" - "TG-Watch"
- "adafruit_feather_rp2040" - "adafruit_feather_rp2040"
- "adafruit_itsybitsy_rp2040"
- "adafruit_neokey_trinkey_m0"
- "adafruit_proxlight_trinkey_m0"
- "adafruit_qtpy_rp2040"
- "adafruit_rotary_trinkey_m0"
- "adafruit_slide_trinkey_m0"
- "aloriumtech_evo_m51" - "aloriumtech_evo_m51"
- "aramcon2_badge"
- "aramcon_badge_2019" - "aramcon_badge_2019"
- "arduino_mkr1300" - "arduino_mkr1300"
- "arduino_mkrzero" - "arduino_mkrzero"
@ -189,6 +195,7 @@ jobs:
- "bastble" - "bastble"
- "bdmicro_vina_d21" - "bdmicro_vina_d21"
- "bdmicro_vina_d51" - "bdmicro_vina_d51"
- "bdmicro_vina_d51_pcb7"
- "bless_dev_board_multi_sensor" - "bless_dev_board_multi_sensor"
- "blm_badge" - "blm_badge"
- "capablerobot_usbhub" - "capablerobot_usbhub"
@ -208,6 +215,7 @@ jobs:
- "datum_imu" - "datum_imu"
- "datum_light" - "datum_light"
- "datum_weather" - "datum_weather"
- "dynalora_usb"
- "dynossat_edu_eps" - "dynossat_edu_eps"
- "dynossat_edu_obc" - "dynossat_edu_obc"
- "electronut_labs_blip" - "electronut_labs_blip"
@ -237,6 +245,7 @@ jobs:
- "hallowing_m0_express" - "hallowing_m0_express"
- "hallowing_m4_express" - "hallowing_m4_express"
- "hiibot_bluefi" - "hiibot_bluefi"
- "huntercat_nfc"
- "ikigaisense_vita" - "ikigaisense_vita"
- "imxrt1010_evk" - "imxrt1010_evk"
- "imxrt1020_evk" - "imxrt1020_evk"
@ -280,6 +289,11 @@ jobs:
- "pewpew10" - "pewpew10"
- "pewpew_m4" - "pewpew_m4"
- "picoplanet" - "picoplanet"
- "pimoroni_keybow2040"
- "pimoroni_picolipo_16mb"
- "pimoroni_picolipo_4mb"
- "pimoroni_picosystem"
- "pimoroni_tiny2040"
- "pirkey_m0" - "pirkey_m0"
- "pitaya_go" - "pitaya_go"
- "pyb_nano_v2" - "pyb_nano_v2"
@ -302,19 +316,24 @@ jobs:
- "same54_xplained" - "same54_xplained"
- "seeeduino_wio_terminal" - "seeeduino_wio_terminal"
- "seeeduino_xiao" - "seeeduino_xiao"
- "sensebox_mcu"
- "serpente" - "serpente"
- "shirtty" - "shirtty"
- "silicognition-m4-shim" - "silicognition-m4-shim"
- "simmel" - "simmel"
- "snekboard" - "snekboard"
- "sparkfun_lumidrive" - "sparkfun_lumidrive"
- "sparkfun_micromod_rp2040"
- "sparkfun_nrf52840_micromod"
- "sparkfun_nrf52840_mini" - "sparkfun_nrf52840_mini"
- "sparkfun_pro_micro_rp2040"
- "sparkfun_qwiic_micro_no_flash" - "sparkfun_qwiic_micro_no_flash"
- "sparkfun_qwiic_micro_with_flash" - "sparkfun_qwiic_micro_with_flash"
- "sparkfun_redboard_turbo" - "sparkfun_redboard_turbo"
- "sparkfun_samd21_dev" - "sparkfun_samd21_dev"
- "sparkfun_samd21_mini" - "sparkfun_samd21_mini"
- "sparkfun_samd51_thing_plus" - "sparkfun_samd51_thing_plus"
- "sparkfun_thing_plus_rp2040"
- "spresense" - "spresense"
- "stackrduino_m0_pro" - "stackrduino_m0_pro"
- "stm32f411ce_blackpill" - "stm32f411ce_blackpill"
@ -346,10 +365,15 @@ jobs:
uses: actions/setup-python@v1 uses: actions/setup-python@v1
with: with:
python-version: 3.8 python-version: 3.8
- uses: actions/checkout@v2.2.0
with:
submodules: true
fetch-depth: 0
- run: git fetch --recurse-submodules=no https://github.com/adafruit/circuitpython refs/tags/*:refs/tags/*
- name: Install deps - name: Install deps
run: | run: |
sudo apt-get install -y gettext sudo apt-get install -y gettext
pip install requests sh click setuptools awscli pip install -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 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 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
@ -357,13 +381,10 @@ jobs:
gcc --version gcc --version
arm-none-eabi-gcc --version arm-none-eabi-gcc --version
python3 --version python3 --version
- uses: actions/checkout@v2.2.0
with:
submodules: true
fetch-depth: 0
- run: git fetch --recurse-submodules=no https://github.com/adafruit/circuitpython refs/tags/*:refs/tags/*
- name: mpy-cross - name: mpy-cross
run: make -C mpy-cross -j2 run: make -C mpy-cross -j2
- name: Setup build failure matcher
run: echo "::add-matcher::$GITHUB_WORKSPACE/.github/workflows/match-build-fail.json"
- name: build - name: build
run: python3 -u build_release_files.py run: python3 -u build_release_files.py
working-directory: tools working-directory: tools
@ -395,6 +416,11 @@ jobs:
uses: actions/setup-python@v1 uses: actions/setup-python@v1
with: with:
python-version: 3.8 python-version: 3.8
- uses: actions/checkout@v2.2.0
with:
submodules: true
fetch-depth: 0
- run: git fetch --recurse-submodules=no https://github.com/adafruit/circuitpython refs/tags/*:refs/tags/*
- name: Install deps - name: Install deps
run: | run: |
sudo apt-get install -y gettext sudo apt-get install -y gettext
@ -406,13 +432,10 @@ jobs:
gcc --version gcc --version
riscv64-unknown-elf-gcc --version riscv64-unknown-elf-gcc --version
python3 --version python3 --version
- uses: actions/checkout@v2.2.0
with:
submodules: true
fetch-depth: 0
- run: git fetch --recurse-submodules=no https://github.com/adafruit/circuitpython refs/tags/*:refs/tags/*
- name: mpy-cross - name: mpy-cross
run: make -C mpy-cross -j2 run: make -C mpy-cross -j2
- name: Setup build failure matcher
run: echo "::add-matcher::$GITHUB_WORKSPACE/.github/workflows/match-build-fail.json"
- name: build - name: build
run: python3 -u build_release_files.py run: python3 -u build_release_files.py
working-directory: tools working-directory: tools
@ -438,12 +461,17 @@ jobs:
board: board:
- "adafruit_feather_esp32s2_nopsram" - "adafruit_feather_esp32s2_nopsram"
- "adafruit_feather_esp32s2_tftback_nopsram" - "adafruit_feather_esp32s2_tftback_nopsram"
- "adafruit_funhouse"
- "adafruit_magtag_2.9_grayscale" - "adafruit_magtag_2.9_grayscale"
- "adafruit_metro_esp32s2" - "adafruit_metro_esp32s2"
- "artisense_rd00"
- "atmegazero_esp32s2"
- "electroniccats_bastwifi" - "electroniccats_bastwifi"
- "espressif_kaluga_1" - "espressif_kaluga_1"
- "espressif_saola_1_wroom" - "espressif_saola_1_wroom"
- "espressif_saola_1_wrover" - "espressif_saola_1_wrover"
- "franzininho_wifi_wroom"
- "franzininho_wifi_wrover"
- "lilygo_ttgo_t8_s2_st7789" - "lilygo_ttgo_t8_s2_st7789"
- "microdev_micro_s2" - "microdev_micro_s2"
- "muselab_nanoesp32_s2" - "muselab_nanoesp32_s2"
@ -451,6 +479,7 @@ jobs:
- "targett_module_clip_wrover" - "targett_module_clip_wrover"
- "unexpectedmaker_feathers2" - "unexpectedmaker_feathers2"
- "unexpectedmaker_feathers2_prerelease" - "unexpectedmaker_feathers2_prerelease"
- "unexpectedmaker_tinys2"
steps: steps:
- name: Set up Python 3.8 - name: Set up Python 3.8
@ -469,7 +498,7 @@ jobs:
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/esp32s2/esp-idf/HEAD') }}-20210128 key: ${{ runner.os }}-idf-tools-${{ hashFiles('.git/modules/ports/esp32s2/esp-idf/HEAD') }}-20210422
- name: Clone IDF submodules - name: Clone IDF submodules
run: | run: |
(cd $IDF_PATH && git submodule update --init) (cd $IDF_PATH && git submodule update --init)
@ -487,7 +516,7 @@ jobs:
- name: Install CircuitPython deps - name: Install CircuitPython deps
run: | run: |
source $IDF_PATH/export.sh source $IDF_PATH/export.sh
pip install requests sh click setuptools awscli pip install -r requirements-dev.txt
sudo apt-get install -y gettext ninja-build sudo apt-get install -y gettext ninja-build
env: env:
IDF_PATH: ${{ github.workspace }}/ports/esp32s2/esp-idf IDF_PATH: ${{ github.workspace }}/ports/esp32s2/esp-idf
@ -506,6 +535,8 @@ jobs:
IDF_TOOLS_PATH: ${{ github.workspace }}/.idf_tools IDF_TOOLS_PATH: ${{ github.workspace }}/.idf_tools
- name: mpy-cross - name: mpy-cross
run: make -C mpy-cross -j2 run: make -C mpy-cross -j2
- name: Setup build failure matcher
run: echo "::add-matcher::$GITHUB_WORKSPACE/.github/workflows/match-build-fail.json"
- name: build - name: build
run: | run: |
source $IDF_PATH/export.sh source $IDF_PATH/export.sh

View file

@ -16,21 +16,21 @@ 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
with:
submodules: true
fetch-depth: 0
- name: Set up Python 3.8 - name: Set up Python 3.8
uses: actions/setup-python@v1 uses: actions/setup-python@v1
with: with:
python-version: 3.8 python-version: 3.8
- name: Install deps - name: Install deps
run: | run: |
pip install requests sh click pip install -r requirements-dev.txt
- name: Versions - name: Versions
run: | run: |
gcc --version gcc --version
python3 --version python3 --version
- uses: actions/checkout@v2.2.0
with:
submodules: true
fetch-depth: 0
- run: git fetch --recurse-submodules=no https://github.com/adafruit/circuitpython refs/tags/*:refs/tags/* - run: git fetch --recurse-submodules=no https://github.com/adafruit/circuitpython refs/tags/*:refs/tags/*
- name: CircuitPython version - name: CircuitPython version
run: git describe --dirty --tags run: git describe --dirty --tags

14
.github/workflows/match-build-fail.json vendored Normal file
View file

@ -0,0 +1,14 @@
{
"problemMatcher": [
{
"severity": "error",
"pattern": [
{
"regexp": "^(Build .+ and \\x1b\\[31mfailed\\x1b\\[0m)$",
"message": 1
}
],
"owner": "build-failed"
}
]
}

View file

@ -7,7 +7,6 @@ name: pre-commit
on: on:
pull_request: pull_request:
push: push:
branches: [main]
jobs: jobs:
pre-commit: pre-commit:
@ -16,10 +15,13 @@ jobs:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
- uses: actions/setup-python@v1 - uses: actions/setup-python@v1
- name: Install deps - name: Install deps
run: sudo apt-get update && sudo apt-get install -y gettext run: |
sudo apt-add-repository -y -u ppa:pybricks/ppa
sudo apt-get install -y black gettext uncrustify
pip3 install -r requirements-dev.txt
- 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@v2
with: with:

3
.gitignore vendored
View file

@ -86,3 +86,6 @@ TAGS
#################### ####################
.venv .venv
.env .env
# Uncrustify formatting
*.uncrustify

12
.gitmodules vendored
View file

@ -171,6 +171,16 @@
[submodule "frozen/Adafruit_CircuitPython_LC709203F"] [submodule "frozen/Adafruit_CircuitPython_LC709203F"]
path = frozen/Adafruit_CircuitPython_LC709203F path = frozen/Adafruit_CircuitPython_LC709203F
url = https://github.com/adafruit/Adafruit_CircuitPython_LC709203F url = https://github.com/adafruit/Adafruit_CircuitPython_LC709203F
[submodule "frozen/Adafruit_CircuitPython_SimpleMath"]
path = frozen/Adafruit_CircuitPython_SimpleMath
url = https://github.com/adafruit/Adafruit_CircuitPython_SimpleMath
[submodule "ports/raspberrypi/sdk"] [submodule "ports/raspberrypi/sdk"]
path = ports/raspberrypi/sdk path = ports/raspberrypi/sdk
url = https://github.com/raspberrypi/pico-sdk.git url = https://github.com/adafruit/pico-sdk.git
[submodule "data/nvm.toml"]
path = data/nvm.toml
url = https://github.com/adafruit/nvm.toml.git
branch = main
[submodule "frozen/Adafruit_CircuitPython_MIDI"]
path = frozen/Adafruit_CircuitPython_MIDI
url = https://github.com/adafruit/Adafruit_CircuitPython_MIDI

View file

@ -11,3 +11,16 @@ repos:
exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*|ports/esp32s2/esp-idf-config/.*|ports/esp32s2/boards/.*/sdkconfig)' exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*|ports/esp32s2/esp-idf-config/.*|ports/esp32s2/boards/.*/sdkconfig)'
- id: trailing-whitespace - id: trailing-whitespace
exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*)' exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*)'
- repo: local
hooks:
- id: translations
name: Translations
entry: sh -c "if ! make check-translate; then make translate; fi"
types: [c]
pass_filenames: false
language: system
- id: formatting
name: Formatting
entry: python3 tools/codeformat.py
types_or: [c, python]
language: system

View file

@ -85,3 +85,23 @@ Example:
If your port/build includes `arm-none-eabi-gdb-py`, consider using it instead, as it can be used for better register If your port/build includes `arm-none-eabi-gdb-py`, consider using it instead, as it can be used for better register
debugging with https://github.com/bnahill/PyCortexMDebug debugging with https://github.com/bnahill/PyCortexMDebug
# Code Quality Checks
We apply code quality checks using pre-commit. Install pre-commit once per system with
python3 -mpip install pre-commit
Activate it once per git clone with
pre-commit --install
Pre-commit also requires some additional programs to be installed through your package manager:
* Standard Unix tools such as make, find, etc
* The gettext package, any modern version
* uncrustify version 0.71 (0.72 is also tested)
Each time you create a git commit, the pre-commit quality checks will be run. You can also run them e.g., with `pre-commit run foo.c` or `pre-commit run --all` to run on all files whether modified or not.
Some pre-commit quality checks require your active attention to resolve, others (such as the formatting checks of uncrustify) are made automatically and must simply be incorporated into your code changes by committing them.

View file

@ -51,6 +51,10 @@ Specifically useful documentation when starting out:
- `CircuitPython Essentials <https://learn.adafruit.com/circuitpython-essentials>`__ - `CircuitPython Essentials <https://learn.adafruit.com/circuitpython-essentials>`__
- `Example Code <https://github.com/adafruit/Adafruit_Learning_System_Guides/tree/master/CircuitPython_Essentials>`__ - `Example Code <https://github.com/adafruit/Adafruit_Learning_System_Guides/tree/master/CircuitPython_Essentials>`__
Code Search
------------
GitHub doesn't currently support code search on forks. Therefore, CircuitPython doesn't have code search through GitHub because it is a fork of MicroPython. Luckily, `SourceGraph <https://sourcegraph.com/github.com/adafruit/circuitpython>`_ has free code search for public repos like CircuitPython. So, visit `sourcegraph.com/github.com/adafruit/circuitpython <https://sourcegraph.com/github.com/adafruit/circuitpython>`_ to search the CircuitPython codebase online.
Contributing Contributing
------------ ------------
@ -113,10 +117,9 @@ Behavior
- ``code.py`` (or ``main.py``) is run after every reload until it - ``code.py`` (or ``main.py``) is run after every reload until it
finishes or is interrupted. After it is done running, the vm and finishes or is interrupted. After it is done running, the vm and
hardware is reinitialized. **This means you cannot read state from** hardware is reinitialized. **This means you cannot read state from**
``code.py`` **in the REPL anymore.** CircuitPython's goal for this ``code.py`` **in the REPL anymore, as the REPL is a fresh vm.** CircuitPython's goal for this
change includes reducing confusion about pins and memory being used. change includes reducing confusion about pins and memory being used.
- After ``code.py`` the REPL can be entered by pressing any key. It no - After the main code is finished the REPL can be entered by pressing any key.
longer shares state with ``code.py`` so it is a fresh vm.
- Autoreload state will be maintained across reload. - Autoreload state will be maintained across reload.
- Adds a safe mode that does not run user code after a hard crash or - Adds a safe mode that does not run user code after a hard crash or
brown out. The hope is that this will make it easier to fix code that brown out. The hope is that this will make it easier to fix code that
@ -126,8 +129,7 @@ Behavior
- RGB status LED indicating CircuitPython state, and errors through a sequence of colored flashes. - RGB status LED indicating CircuitPython state, and errors through a sequence of colored flashes.
- Re-runs ``code.py`` or other main file after file system writes over USB mass storage. (Disable with - Re-runs ``code.py`` or other main file after file system writes over USB mass storage. (Disable with
``supervisor.disable_autoreload()``) ``supervisor.disable_autoreload()``)
- Entering the REPL after the main code is finished requires a key press which enters the REPL and - Autoreload is disabled while the REPL is active.
disables autoreload.
- Main is one of these: ``code.txt``, ``code.py``, ``main.py``, - Main is one of these: ``code.txt``, ``code.py``, ``main.py``,
``main.txt`` ``main.txt``
- Boot is one of these: ``settings.txt``, ``settings.py``, ``boot.py``, - Boot is one of these: ``settings.txt``, ``settings.py``, ``boot.py``,
@ -209,6 +211,7 @@ esp32s2 beta
litex alpha litex alpha
mimxrt10xx alpha mimxrt10xx alpha
nrf stable nrf stable
raspberrypi beta
stm ``F4`` stable | ``others`` beta stm ``F4`` stable | ``others`` beta
unix alpha unix alpha
================ ============================================================ ================ ============================================================

94
WEBUSB_README.md Normal file
View file

@ -0,0 +1,94 @@
<!--
SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
SPDX-License-Identifier: MIT
-->
# WebUSB Serial Support
To date, this has only been tested on one port (esp32s2), on one board (espressif_kaluga_1).
## What it does
If you have ever used CircuitPython on a platform with a graphical LCD display, you have probably
already seen multiple "consoles" in use (although the LCD console is "output only").
New compile-time option CIRCUITPY_USB_VENDOR enables an additional "console" that can be used in
parallel with the original (CDC) serial console.
Web pages that support the WebUSB standard can connect to the "vendor" interface and activate
this WebUSB serial console at any time.
You can type into either console, and CircuitPython output is sent to all active consoles.
One example of a web page you can use to test drive this feature can be found at:
https://adafruit.github.io/Adafruit_TinyUSB_Arduino/examples/webusb-serial/index.html
## How to enable
Update your platform's mpconfigboard.mk file to enable and disable specific types of USB interfaces.
CIRCUITPY_USB_HID = xxx
CIRCUITPY_USB_MIDI = xxx
CIRCUITPY_USB_VENDOR = xxx
On at least some of the hardware platforms, the maximum number of USB endpoints is fixed.
For example, on the ESP32S2, you must pick only one of the above 3 interfaces to be enabled.
Original espressif_kaluga_1 mpconfigboard.mk settings:
CIRCUITPY_USB_HID = 1
CIRCUITPY_USB_MIDI = 0
CIRCUITPY_USB_VENDOR = 0
Settings to enable WebUSB instead:
CIRCUITPY_USB_HID = 0
CIRCUITPY_USB_MIDI = 0
CIRCUITPY_USB_VENDOR = 1
Notice that to enable VENDOR on ESP32-S2, we had to give up HID. There may be platforms that can have both, or even all three.
## Implementation Notes
CircuitPython uses the tinyusb library.
The tinyusb library already has support for WebUSB serial.
The tinyusb examples already include a "WebUSB serial" example.
Sidenote - The use of the term "vendor" instead of "WebUSB" was done to match tinyusb.
Basically, this feature was ported into CircuitPython by pulling code snippets out of the
tinyusb example, and putting them where they best belonged in the CircuitPython codebase.
There was one complication:
tinyusb uses C preprocessor macros to define things like USB descriptors.
CircuitPython uses a Python program (tools/gen_usb_descriptor.py) to create USB descriptors (etc.)
using "helper objects" from another repo (adafruit_usb_descriptor). This means some of the example
code had to be adapted to the new programing model, and gen_usb_descriptor gained new command-line
options to control the generated code.
The generated files go into the "build" directory, look for autogen_usb_descriptor.c and
genhdr/autogen_usb_descriptor.h.
Also worth pointing out - the re-use of the CDC connect/disconnect mechanism is not actually part
of the WebUSB standard, it's more of "common idiom". We make use of it here because we need to know
when we should be paying attention to the WebUSB serial interface, and when we should ignore it..
## Possible future work areas
The current code uses the existing Python infrastructure to create the Interface descriptor, but
simply outputs the code snippets from the original tinyusb demo code to create the WEBUSB_URL,
BOS, and MS_OS_20 descriptors. I suppose additional work could be done to add these to the
adafruit_usb_descriptor project, and then gen_usb_descriptor.py could be modified to make use
of them.
Program gen_usb_descriptor.py creates objects for most interface types, regardless of whether or
not they are actually enabled. This increases the size of a generated string table. I made the
new vendor-interface-related code not do this (because some of the ARM platforms would no longer
build), but I did not go back and do this for the other interface types (CDC, MIDI, HID, etc.)
Some FLASH savings are probably possible if this is done.

View file

@ -150,9 +150,11 @@ version = release = final_version
# directories to ignore when looking for source files. # directories to ignore when looking for source files.
exclude_patterns = ["**/build*", exclude_patterns = ["**/build*",
".git", ".git",
".github",
".env", ".env",
".venv", ".venv",
".direnv", ".direnv",
"data",
"docs/autoapi", "docs/autoapi",
"docs/README.md", "docs/README.md",
"drivers", "drivers",
@ -178,6 +180,7 @@ exclude_patterns = ["**/build*",
"ports/cxd56/spresense-exported-sdk", "ports/cxd56/spresense-exported-sdk",
"ports/esp32s2/certificates", "ports/esp32s2/certificates",
"ports/esp32s2/esp-idf", "ports/esp32s2/esp-idf",
"ports/esp32s2/.idf_tools",
"ports/esp32s2/peripherals", "ports/esp32s2/peripherals",
"ports/litex/hw", "ports/litex/hw",
"ports/minimal", "ports/minimal",
@ -281,7 +284,7 @@ html_static_path = ['docs/static']
# Add any extra paths that contain custom files (such as robots.txt or # Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied # .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation. # directly to the root of the documentation.
html_extra_path = ["docs/robots.txt"] #html_extra_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format. # using the given strftime format.
@ -486,6 +489,8 @@ class CoreModuleTransform(SphinxTransform):
def setup(app): def setup(app):
app.add_css_file("customstyle.css") app.add_css_file("customstyle.css")
app.add_css_file("filter.css")
app.add_js_file("filter.js")
app.add_config_value('redirects_file', 'redirects', 'env') app.add_config_value('redirects_file', 'redirects', 'env')
app.connect('builder-inited', generate_redirects) app.connect('builder-inited', generate_redirects)
app.add_transform(CoreModuleTransform) app.add_transform(CoreModuleTransform)

1
data/nvm.toml Submodule

@ -0,0 +1 @@
Subproject commit 9b4a5241d8c3310b31a7925a4f2160743890a2e4

View file

@ -51,7 +51,7 @@
#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)
// 0.625 msecs (625 usecs) // 0.625 msecs (625 usecs)
#define ADV_INTERVAL_UNIT_FLOAT_SECS (0.000625) #define ADV_INTERVAL_UNIT_FLOAT_SECS (0.000625)
// Microseconds is the base unit. The macros above know that. // Microseconds is the base unit. The macros above know that.
@ -63,7 +63,7 @@
// TODO make this settable from Python. // TODO make this settable from Python.
#define DEFAULT_TX_POWER 0 // 0 dBm #define DEFAULT_TX_POWER 0 // 0 dBm
#define MAX_ANONYMOUS_ADV_TIMEOUT_SECS (60*15) #define MAX_ANONYMOUS_ADV_TIMEOUT_SECS (60 * 15)
#define MAX_LIMITED_DISCOVERABLE_ADV_TIMEOUT_SECS (180) #define MAX_LIMITED_DISCOVERABLE_ADV_TIMEOUT_SECS (180)
#define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS) #define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS)
@ -289,7 +289,7 @@ STATIC void bleio_adapter_hci_init(bleio_adapter_obj_t *self) {
// 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,
&self->manufacturer, &self->lmp_subversion) != HCI_OK) { &self->manufacturer, &self->lmp_subversion) != HCI_OK) {
mp_raise_bleio_BluetoothError(translate("Could not read HCI version")); mp_raise_bleio_BluetoothError(translate("Could not read HCI version"));
} }
// Get supported features. // Get supported features.
@ -414,11 +414,11 @@ bool common_hal_bleio_adapter_set_address(bleio_adapter_obj_t *self, bleio_addre
return hci_le_set_random_address(bufinfo.buf) == HCI_OK; return hci_le_set_random_address(bufinfo.buf) == HCI_OK;
} }
mp_obj_str_t* common_hal_bleio_adapter_get_name(bleio_adapter_obj_t *self) { mp_obj_str_t *common_hal_bleio_adapter_get_name(bleio_adapter_obj_t *self) {
return self->name; return self->name;
} }
void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char* name) { void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char *name) {
self->name = mp_obj_new_str(name, strlen(name)); self->name = mp_obj_new_str(name, strlen(name));
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
mp_get_buffer_raise(self->name, &bufinfo, MP_BUFFER_READ); mp_get_buffer_raise(self->name, &bufinfo, MP_BUFFER_READ);
@ -459,7 +459,7 @@ void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char* na
// return true; // return true;
// } // }
mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t* prefixes, size_t prefix_length, bool extended, mp_int_t buffer_size, mp_float_t timeout, mp_float_t interval, mp_float_t window, mp_int_t minimum_rssi, bool active) { mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t *prefixes, size_t prefix_length, bool extended, mp_int_t buffer_size, mp_float_t timeout, mp_float_t interval, mp_float_t window, mp_int_t minimum_rssi, bool active) {
// TODO // TODO
mp_raise_NotImplementedError(NULL); mp_raise_NotImplementedError(NULL);
check_enabled(self); check_enabled(self);
@ -704,7 +704,7 @@ uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self,
uint8_t handle[1] = { 0 }; uint8_t handle[1] = { 0 };
uint16_t duration_10msec[1] = { timeout * 100 }; uint16_t duration_10msec[1] = { timeout * 100 };
uint8_t max_ext_adv_evts[1] = { 0 }; uint8_t max_ext_adv_evts[1] = { 0 };
hci_check_error( hci_check_error(
hci_le_set_extended_advertising_enable( hci_le_set_extended_advertising_enable(
BT_HCI_LE_ADV_ENABLE, BT_HCI_LE_ADV_ENABLE,
@ -789,11 +789,11 @@ void common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool
} else { } else {
if (timeout > MAX_LIMITED_DISCOVERABLE_ADV_TIMEOUT_SECS) { if (timeout > MAX_LIMITED_DISCOVERABLE_ADV_TIMEOUT_SECS) {
mp_raise_bleio_BluetoothError(translate("Timeout is too long: Maximum timeout length is %d seconds"), mp_raise_bleio_BluetoothError(translate("Timeout is too long: Maximum timeout length is %d seconds"),
MAX_LIMITED_DISCOVERABLE_ADV_TIMEOUT_SECS); MAX_LIMITED_DISCOVERABLE_ADV_TIMEOUT_SECS);
} }
} }
const uint32_t result =_common_hal_bleio_adapter_start_advertising( const uint32_t result = _common_hal_bleio_adapter_start_advertising(
self, connectable, anonymous, timeout, interval, self, connectable, anonymous, timeout, interval,
advertising_data_bufinfo->buf, advertising_data_bufinfo->buf,
advertising_data_bufinfo->len, advertising_data_bufinfo->len,
@ -820,11 +820,11 @@ void common_hal_bleio_adapter_stop_advertising(bleio_adapter_obj_t *self) {
hci_check_error(result); hci_check_error(result);
} }
//TODO startup CircuitPython advertising again. // TODO startup CircuitPython advertising again.
} }
// Note that something stopped advertising, such as a connection happening. // Note that something stopped advertising, such as a connection happening.
//Don't ask the adapter to stop. // Don't ask the adapter to stop.
void bleio_adapter_advertising_was_stopped(bleio_adapter_obj_t *self) { void bleio_adapter_advertising_was_stopped(bleio_adapter_obj_t *self) {
self->now_advertising = false; self->now_advertising = false;
self->extended_advertising = false; self->extended_advertising = false;
@ -876,14 +876,14 @@ void common_hal_bleio_adapter_erase_bonding(bleio_adapter_obj_t *self) {
mp_raise_NotImplementedError(NULL); mp_raise_NotImplementedError(NULL);
check_enabled(self); check_enabled(self);
//FIX bonding_erase_storage(); // FIX bonding_erase_storage();
} }
uint16_t bleio_adapter_add_attribute(bleio_adapter_obj_t *adapter, mp_obj_t *attribute) { uint16_t bleio_adapter_add_attribute(bleio_adapter_obj_t *adapter, mp_obj_t *attribute) {
check_enabled(adapter); check_enabled(adapter);
// The handle is the index of this attribute in the attributes list. // The handle is the index of this attribute in the attributes list.
uint16_t handle = (uint16_t) adapter->attributes->len; uint16_t handle = (uint16_t)adapter->attributes->len;
mp_obj_list_append(adapter->attributes, attribute); mp_obj_list_append(adapter->attributes, attribute);
if (MP_OBJ_IS_TYPE(attribute, &bleio_service_type)) { if (MP_OBJ_IS_TYPE(attribute, &bleio_service_type)) {
@ -896,7 +896,7 @@ uint16_t bleio_adapter_add_attribute(bleio_adapter_obj_t *adapter, mp_obj_t *att
return handle; return handle;
} }
mp_obj_t* bleio_adapter_get_attribute(bleio_adapter_obj_t *adapter, uint16_t handle) { mp_obj_t *bleio_adapter_get_attribute(bleio_adapter_obj_t *adapter, uint16_t handle) {
check_enabled(adapter); check_enabled(adapter);
if (handle == 0 || handle >= adapter->attributes->len) { if (handle == 0 || handle >= adapter->attributes->len) {
@ -912,12 +912,12 @@ uint16_t bleio_adapter_max_attribute_handle(bleio_adapter_obj_t *adapter) {
} }
void bleio_adapter_gc_collect(bleio_adapter_obj_t* adapter) { void bleio_adapter_gc_collect(bleio_adapter_obj_t *adapter) {
gc_collect_root((void**)adapter, sizeof(bleio_adapter_obj_t) / sizeof(size_t)); gc_collect_root((void **)adapter, sizeof(bleio_adapter_obj_t) / sizeof(size_t));
gc_collect_root((void**)bleio_connections, sizeof(bleio_connections) / sizeof(size_t)); gc_collect_root((void **)bleio_connections, sizeof(bleio_connections) / sizeof(size_t));
} }
void bleio_adapter_reset(bleio_adapter_obj_t* adapter) { void bleio_adapter_reset(bleio_adapter_obj_t *adapter) {
if (!common_hal_bleio_adapter_get_enabled(adapter)) { if (!common_hal_bleio_adapter_get_enabled(adapter)) {
return; return;
@ -939,7 +939,7 @@ void bleio_adapter_reset(bleio_adapter_obj_t* adapter) {
} }
void bleio_adapter_background(bleio_adapter_obj_t* adapter) { void bleio_adapter_background(bleio_adapter_obj_t *adapter) {
if (!common_hal_bleio_adapter_get_enabled(adapter)) { if (!common_hal_bleio_adapter_get_enabled(adapter)) {
return; return;
} }

View file

@ -49,7 +49,7 @@ typedef struct _bleio_adapter_obj_t {
bleio_scanresults_obj_t *scan_results; bleio_scanresults_obj_t *scan_results;
mp_obj_t name; mp_obj_t name;
mp_obj_tuple_t *connection_objs; mp_obj_tuple_t *connection_objs;
busio_uart_obj_t* hci_uart; busio_uart_obj_t *hci_uart;
digitalio_digitalinout_obj_t *rts_digitalinout; digitalio_digitalinout_obj_t *rts_digitalinout;
digitalio_digitalinout_obj_t *cts_digitalinout; digitalio_digitalinout_obj_t *cts_digitalinout;
bool allocated; // True when in use. bool allocated; // True when in use.
@ -72,7 +72,7 @@ typedef struct _bleio_adapter_obj_t {
// Generic services characteristics. // Generic services characteristics.
bleio_characteristic_obj_t *device_name_characteristic; bleio_characteristic_obj_t *device_name_characteristic;
bleio_characteristic_obj_t *appearance_characteristic; bleio_characteristic_obj_t *appearance_characteristic;
bleio_characteristic_obj_t * service_changed_characteristic; bleio_characteristic_obj_t *service_changed_characteristic;
uint16_t max_acl_buffer_len; uint16_t max_acl_buffer_len;
uint16_t max_acl_num_buffers; uint16_t max_acl_num_buffers;
@ -90,10 +90,10 @@ typedef struct _bleio_adapter_obj_t {
uint16_t bleio_adapter_add_attribute(bleio_adapter_obj_t *adapter, mp_obj_t *attribute); uint16_t bleio_adapter_add_attribute(bleio_adapter_obj_t *adapter, mp_obj_t *attribute);
void bleio_adapter_advertising_was_stopped(bleio_adapter_obj_t *self); void bleio_adapter_advertising_was_stopped(bleio_adapter_obj_t *self);
mp_obj_t* bleio_adapter_get_attribute(bleio_adapter_obj_t *adapter, uint16_t handle); mp_obj_t *bleio_adapter_get_attribute(bleio_adapter_obj_t *adapter, uint16_t handle);
uint16_t bleio_adapter_max_attribute_handle(bleio_adapter_obj_t *adapter); uint16_t bleio_adapter_max_attribute_handle(bleio_adapter_obj_t *adapter);
void bleio_adapter_background(bleio_adapter_obj_t* adapter); void bleio_adapter_background(bleio_adapter_obj_t *adapter);
void bleio_adapter_gc_collect(bleio_adapter_obj_t* adapter); void bleio_adapter_gc_collect(bleio_adapter_obj_t *adapter);
void bleio_adapter_reset(bleio_adapter_obj_t* adapter); void bleio_adapter_reset(bleio_adapter_obj_t *adapter);
#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_ADAPTER_H #endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_ADAPTER_H

View file

@ -78,16 +78,20 @@ bleio_service_obj_t *common_hal_bleio_characteristic_get_service(bleio_character
return self->service; return self->service;
} }
size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self, uint8_t* buf, size_t len) { size_t common_hal_bleio_characteristic_get_max_length(bleio_characteristic_obj_t *self) {
return self->max_length;
}
size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self, uint8_t *buf, size_t len) {
// Do GATT operations only if this characteristic has been added to a registered service. // Do GATT operations only if this characteristic has been added to a registered service.
if (self->handle != BLE_GATT_HANDLE_INVALID) { if (self->handle != BLE_GATT_HANDLE_INVALID) {
//FIX uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection); // FIX uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection);
if (common_hal_bleio_service_get_is_remote(self->service)) { if (common_hal_bleio_service_get_is_remote(self->service)) {
//FIX read remote chars // FIX read remote chars
//uint8_t rsp[MAX(len, 512)]; // uint8_t rsp[MAX(len, 512)];
//FIX improve att_read_req to write into our requested buffer. // FIX improve att_read_req to write into our requested buffer.
// return att_read_req(conn_handle, self->handle, rsp); // return att_read_req(conn_handle, self->handle, rsp);
return 0; //FIX return 0; // FIX
} else { } else {
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
if (!mp_get_buffer(self->value, &bufinfo, MP_BUFFER_READ)) { if (!mp_get_buffer(self->value, &bufinfo, MP_BUFFER_READ)) {
@ -113,13 +117,13 @@ void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self,
// Do GATT operations only if this characteristic has been added to a registered service. // Do GATT operations only if this characteristic has been added to a registered service.
if (self->handle != BLE_GATT_HANDLE_INVALID) { if (self->handle != BLE_GATT_HANDLE_INVALID) {
if (common_hal_bleio_service_get_is_remote(self->service)) { if (common_hal_bleio_service_get_is_remote(self->service)) {
//FIX uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection); // FIX uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection);
if (self->props & CHAR_PROP_WRITE) { if (self->props & CHAR_PROP_WRITE) {
//FIX writing remote chars // FIX writing remote chars
//uint8_t rsp[sizeof(bt_att_error_rsp)]; // uint8_t rsp[sizeof(bt_att_error_rsp)];
//att_write_req(conn_handle, self->handle, bufinfo->buf, bufinfo->len, rsp); // att_write_req(conn_handle, self->handle, bufinfo->buf, bufinfo->len, rsp);
} else if (self->props & CHAR_PROP_WRITE_NO_RESPONSE) { } else if (self->props & CHAR_PROP_WRITE_NO_RESPONSE) {
//att_write_cmd(conn_handle, self->handle, bufinfo->buff, bufinfo->len); // att_write_cmd(conn_handle, self->handle, bufinfo->buff, bufinfo->len);
} else { } else {
mp_raise_bleio_BluetoothError(translate("Characteristic not writable")); mp_raise_bleio_BluetoothError(translate("Characteristic not writable"));
} }
@ -172,7 +176,7 @@ void common_hal_bleio_characteristic_add_descriptor(bleio_characteristic_obj_t *
self->service->end_handle = descriptor->handle; self->service->end_handle = descriptor->handle;
mp_obj_list_append(MP_OBJ_FROM_PTR(self->descriptor_list), mp_obj_list_append(MP_OBJ_FROM_PTR(self->descriptor_list),
MP_OBJ_FROM_PTR(descriptor)); MP_OBJ_FROM_PTR(descriptor));
} }
void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, bool notify, bool indicate) { void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, bool notify, bool indicate) {
@ -191,8 +195,8 @@ void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self,
(notify ? CCCD_NOTIFY : 0) | (notify ? CCCD_NOTIFY : 0) |
(indicate ? CCCD_INDICATE : 0); (indicate ? CCCD_INDICATE : 0);
//FIX do remote // FIX do remote
(void) cccd_value; (void)cccd_value;
// uint8_t rsp[sizeof(bt_att_error_rsp)]; // uint8_t rsp[sizeof(bt_att_error_rsp)];
// if (att_write_req(conn_handle, self->cccd->handle, &cccd_value, sizeof(cccd_value)) == 0) { // if (att_write_req(conn_handle, self->cccd->handle, &cccd_value, sizeof(cccd_value)) == 0) {
// mp_raise_bleio_BluetoothError(translate("Could not write CCCD")); // mp_raise_bleio_BluetoothError(translate("Could not write CCCD"));

View file

@ -47,9 +47,9 @@ void bleio_characteristic_buffer_update(bleio_characteristic_buffer_obj_t *self,
// Assumes that timeout and buffer_size have been validated before call. // Assumes that timeout and buffer_size have been validated before call.
void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffer_obj_t *self, void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffer_obj_t *self,
bleio_characteristic_obj_t *characteristic, bleio_characteristic_obj_t *characteristic,
mp_float_t timeout, mp_float_t timeout,
size_t buffer_size) { size_t buffer_size) {
self->characteristic = characteristic; self->characteristic = characteristic;
self->timeout_ms = timeout * 1000; self->timeout_ms = timeout * 1000;
@ -64,10 +64,10 @@ uint32_t common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer
uint64_t start_ticks = supervisor_ticks_ms64(); uint64_t start_ticks = supervisor_ticks_ms64();
// Wait for all bytes received or timeout // Wait for all bytes received or timeout
while ( (ringbuf_num_filled(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) { while ((ringbuf_num_filled(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms)) {
RUN_BACKGROUND_TASKS; RUN_BACKGROUND_TASKS;
// Allow user to break out of a timeout with a KeyboardInterrupt. // Allow user to break out of a timeout with a KeyboardInterrupt.
if ( mp_hal_is_interrupted() ) { if (mp_hal_is_interrupted()) {
return 0; return 0;
} }
} }
@ -97,8 +97,8 @@ void common_hal_bleio_characteristic_buffer_deinit(bleio_characteristic_buffer_o
bool common_hal_bleio_characteristic_buffer_connected(bleio_characteristic_buffer_obj_t *self) { bool common_hal_bleio_characteristic_buffer_connected(bleio_characteristic_buffer_obj_t *self) {
return self->characteristic != NULL && return self->characteristic != NULL &&
self->characteristic->service != NULL && self->characteristic->service != NULL &&
(!self->characteristic->service->is_remote || (!self->characteristic->service->is_remote ||
(self->characteristic->service->connection != MP_OBJ_NULL && (self->characteristic->service->connection != MP_OBJ_NULL &&
common_hal_bleio_connection_get_connected(self->characteristic->service->connection))); common_hal_bleio_connection_get_connected(self->characteristic->service->connection)));
} }

View file

@ -73,8 +73,8 @@
static volatile bool m_discovery_in_process; static volatile bool m_discovery_in_process;
static volatile bool m_discovery_successful; static volatile bool m_discovery_successful;
//FIX static bleio_service_obj_t *m_char_discovery_service; // FIX static bleio_service_obj_t *m_char_discovery_service;
//FIX static bleio_characteristic_obj_t *m_desc_discovery_characteristic; // FIX static bleio_characteristic_obj_t *m_desc_discovery_characteristic;
// bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { // bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
// bleio_connection_internal_t *self = (bleio_connection_internal_t*)self_in; // bleio_connection_internal_t *self = (bleio_connection_internal_t*)self_in;
@ -326,7 +326,7 @@ void bleio_connection_clear(bleio_connection_internal_t *self) {
self->conn_handle = BLE_CONN_HANDLE_INVALID; self->conn_handle = BLE_CONN_HANDLE_INVALID;
self->pair_status = PAIR_NOT_PAIRED; self->pair_status = PAIR_NOT_PAIRED;
self->is_central = false; self->is_central = false;
//FIX bonding_clear_keys(&self->bonding_keys); // FIX bonding_clear_keys(&self->bonding_keys);
} }
bool common_hal_bleio_connection_get_paired(bleio_connection_obj_t *self) { bool common_hal_bleio_connection_get_paired(bleio_connection_obj_t *self) {
@ -350,7 +350,7 @@ void common_hal_bleio_connection_disconnect(bleio_connection_internal_t *self) {
void common_hal_bleio_connection_pair(bleio_connection_internal_t *self, bool bond) { void common_hal_bleio_connection_pair(bleio_connection_internal_t *self, bool bond) {
self->pair_status = PAIR_WAITING; self->pair_status = PAIR_WAITING;
//FIX check_nrf_error(sd_ble_gap_authenticate(self->conn_handle, &pairing_sec_params)); // FIX check_nrf_error(sd_ble_gap_authenticate(self->conn_handle, &pairing_sec_params));
while (self->pair_status == PAIR_WAITING && !mp_hal_is_interrupted()) { while (self->pair_status == PAIR_WAITING && !mp_hal_is_interrupted()) {
RUN_BACKGROUND_TASKS; RUN_BACKGROUND_TASKS;
@ -358,14 +358,14 @@ void common_hal_bleio_connection_pair(bleio_connection_internal_t *self, bool bo
if (mp_hal_is_interrupted()) { if (mp_hal_is_interrupted()) {
return; return;
} }
//FIX check_sec_status(self->sec_status); // FIX check_sec_status(self->sec_status);
} }
mp_float_t common_hal_bleio_connection_get_connection_interval(bleio_connection_internal_t *self) { mp_float_t common_hal_bleio_connection_get_connection_interval(bleio_connection_internal_t *self) {
while (self->conn_params_updating && !mp_hal_is_interrupted()) { while (self->conn_params_updating && !mp_hal_is_interrupted()) {
RUN_BACKGROUND_TASKS; RUN_BACKGROUND_TASKS;
} }
//FIX return 1.25f * self->conn_params.min_conn_interval; // FIX return 1.25f * self->conn_params.min_conn_interval;
return 0.0f; return 0.0f;
} }
@ -729,14 +729,14 @@ void common_hal_bleio_connection_set_connection_interval(bleio_connection_intern
// } // }
mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services(bleio_connection_obj_t *self, mp_obj_t service_uuids_whitelist) { mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services(bleio_connection_obj_t *self, mp_obj_t service_uuids_whitelist) {
//FIX discover_remote_services(self->connection, service_uuids_whitelist); // FIX discover_remote_services(self->connection, service_uuids_whitelist);
bleio_connection_ensure_connected(self); bleio_connection_ensure_connected(self);
// Convert to a tuple and then clear the list so the callee will take ownership. // Convert to a tuple and then clear the list so the callee will take ownership.
mp_obj_tuple_t *services_tuple = mp_obj_tuple_t *services_tuple =
mp_obj_new_tuple(self->connection->remote_service_list->len, mp_obj_new_tuple(self->connection->remote_service_list->len,
self->connection->remote_service_list->items); self->connection->remote_service_list->items);
mp_obj_list_clear(MP_OBJ_FROM_PTR(self->connection->remote_service_list)); mp_obj_list_clear(MP_OBJ_FROM_PTR(self->connection->remote_service_list));
return services_tuple; return services_tuple;
} }
uint16_t bleio_connection_get_conn_handle(bleio_connection_obj_t *self) { uint16_t bleio_connection_get_conn_handle(bleio_connection_obj_t *self) {
@ -746,7 +746,7 @@ uint16_t bleio_connection_get_conn_handle(bleio_connection_obj_t *self) {
return self->connection->conn_handle; return self->connection->conn_handle;
} }
mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t* internal) { mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t *internal) {
if (internal->connection_obj != mp_const_none) { if (internal->connection_obj != mp_const_none) {
return internal->connection_obj; return internal->connection_obj;
} }

View file

@ -60,7 +60,7 @@ typedef struct {
volatile pair_status_t pair_status; volatile pair_status_t pair_status;
uint8_t sec_status; // Internal security status. uint8_t sec_status; // Internal security status.
mp_obj_t connection_obj; mp_obj_t connection_obj;
//REMOVE ble_gap_conn_params_t conn_params; // REMOVE ble_gap_conn_params_t conn_params;
volatile bool conn_params_updating; volatile bool conn_params_updating;
uint16_t mtu; uint16_t mtu;
// Request that CCCD values for this connection be saved, using sys_attr values. // Request that CCCD values for this connection be saved, using sys_attr values.
@ -70,20 +70,20 @@ typedef struct {
// Time of setting do_bond_ccds: we delay a bit to consolidate multiple CCCD changes // Time of setting do_bond_ccds: we delay a bit to consolidate multiple CCCD changes
// into one write. Time is currently in ticks_ms. // into one write. Time is currently in ticks_ms.
uint64_t do_bond_cccds_request_time; uint64_t do_bond_cccds_request_time;
//FIX from att.c // FIX from att.c
uint8_t role; uint8_t role;
bt_addr_le_t addr; bt_addr_le_t addr;
} bleio_connection_internal_t; } bleio_connection_internal_t;
typedef struct { typedef struct {
mp_obj_base_t base; mp_obj_base_t base;
bleio_connection_internal_t* connection; bleio_connection_internal_t *connection;
// The HCI disconnect reason. // The HCI disconnect reason.
uint8_t disconnect_reason; uint8_t disconnect_reason;
} bleio_connection_obj_t; } bleio_connection_obj_t;
uint16_t bleio_connection_get_conn_handle(bleio_connection_obj_t *self); uint16_t bleio_connection_get_conn_handle(bleio_connection_obj_t *self);
mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t* connection); mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t *connection);
bleio_connection_internal_t *bleio_conn_handle_to_connection(uint16_t conn_handle); bleio_connection_internal_t *bleio_conn_handle_to_connection(uint16_t conn_handle);
#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_CONNECTION_H #endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_CONNECTION_H

View file

@ -44,7 +44,7 @@ void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_c
const mp_int_t max_length_max = fixed_length ? BLE_GATTS_FIX_ATTR_LEN_MAX : BLE_GATTS_VAR_ATTR_LEN_MAX; const mp_int_t max_length_max = fixed_length ? BLE_GATTS_FIX_ATTR_LEN_MAX : BLE_GATTS_VAR_ATTR_LEN_MAX;
if (max_length < 0 || max_length > max_length_max) { if (max_length < 0 || max_length > max_length_max) {
mp_raise_ValueError_varg(translate("max_length must be 0-%d when fixed_length is %s"), mp_raise_ValueError_varg(translate("max_length must be 0-%d when fixed_length is %s"),
max_length_max, fixed_length ? "True" : "False"); max_length_max, fixed_length ? "True" : "False");
} }
self->max_length = max_length; self->max_length = max_length;
self->fixed_length = fixed_length; self->fixed_length = fixed_length;
@ -60,14 +60,14 @@ bleio_characteristic_obj_t *common_hal_bleio_descriptor_get_characteristic(bleio
return self->characteristic; return self->characteristic;
} }
size_t common_hal_bleio_descriptor_get_value(bleio_descriptor_obj_t *self, uint8_t* buf, size_t len) { size_t common_hal_bleio_descriptor_get_value(bleio_descriptor_obj_t *self, uint8_t *buf, size_t len) {
// Do GATT operations only if this descriptor has been registered // Do GATT operations only if this descriptor has been registered
if (self->handle != BLE_GATT_HANDLE_INVALID) { if (self->handle != BLE_GATT_HANDLE_INVALID) {
if (common_hal_bleio_service_get_is_remote(self->characteristic->service)) { if (common_hal_bleio_service_get_is_remote(self->characteristic->service)) {
//uint16_t conn_handle = bleio_connection_get_conn_handle(self->characteristic->service->connection); // uint16_t conn_handle = bleio_connection_get_conn_handle(self->characteristic->service->connection);
//FIX have att_read_req fill in a buffer // FIX have att_read_req fill in a buffer
//uint8_t rsp[MAX(len, 512)]; // uint8_t rsp[MAX(len, 512)];
//return att_read_req(conn_handle, self->handle, rsp, len); // return att_read_req(conn_handle, self->handle, rsp, len);
return 0; return 0;
} else { } else {
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
@ -96,7 +96,7 @@ void common_hal_bleio_descriptor_set_value(bleio_descriptor_obj_t *self, mp_buff
// Do GATT operations only if this descriptor has been registered. // Do GATT operations only if this descriptor has been registered.
if (self->handle != BLE_GATT_HANDLE_INVALID) { if (self->handle != BLE_GATT_HANDLE_INVALID) {
if (common_hal_bleio_service_get_is_remote(self->characteristic->service)) { if (common_hal_bleio_service_get_is_remote(self->characteristic->service)) {
//FIX // FIX
// uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection); // uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection);
// att_write_req(conn_handle, self->handle, bufinfo->buf, bufinfo->len, rsp); // att_write_req(conn_handle, self->handle, bufinfo->buf, bufinfo->len, rsp);
} else { } else {

View file

@ -47,7 +47,7 @@ typedef struct _bleio_descriptor_obj {
uint16_t handle; uint16_t handle;
bleio_attribute_security_mode_t read_perm; bleio_attribute_security_mode_t read_perm;
bleio_attribute_security_mode_t write_perm; bleio_attribute_security_mode_t write_perm;
struct _bleio_descriptor_obj* next; struct _bleio_descriptor_obj *next;
} bleio_descriptor_obj_t; } bleio_descriptor_obj_t;
#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_DESCRIPTOR_H #endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_DESCRIPTOR_H

View file

@ -45,13 +45,13 @@ STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uin
// 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_capacity(&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++) {
ringbuf_get(&self->ringbuf); ringbuf_get(&self->ringbuf);
} }
// set an overflow flag? // set an overflow flag?
} }
ringbuf_put_n(&self->ringbuf, (uint8_t*) &len, sizeof(uint16_t)); ringbuf_put_n(&self->ringbuf, (uint8_t *)&len, sizeof(uint16_t));
ringbuf_put_n(&self->ringbuf, data, len); ringbuf_put_n(&self->ringbuf, data, len);
} }
@ -80,8 +80,8 @@ void bleio_packet_buffer_update(bleio_packet_buffer_obj_t *self, mp_buffer_info_
} }
void common_hal_bleio_packet_buffer_construct( void common_hal_bleio_packet_buffer_construct(
bleio_packet_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic, bleio_packet_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic,
size_t buffer_size) { size_t buffer_size, size_t max_packet_size) {
self->characteristic = characteristic; self->characteristic = characteristic;
self->client = self->characteristic->service->is_remote; self->client = self->characteristic->service->is_remote;
@ -101,7 +101,7 @@ void common_hal_bleio_packet_buffer_construct(
} }
if (incoming) { if (incoming) {
if (!ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + characteristic->max_length), false)) { if (!ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + max_packet_size), false)) {
mp_raise_ValueError(translate("Buffer too large and unable to allocate")); mp_raise_ValueError(translate("Buffer too large and unable to allocate"));
} }
} }
@ -110,12 +110,13 @@ void common_hal_bleio_packet_buffer_construct(
self->packet_queued = false; self->packet_queued = false;
self->pending_index = 0; self->pending_index = 0;
self->pending_size = 0; self->pending_size = 0;
self->outgoing[0] = m_malloc(characteristic->max_length, false); self->outgoing[0] = m_malloc(max_packet_size, false);
self->outgoing[1] = m_malloc(characteristic->max_length, false); self->outgoing[1] = m_malloc(max_packet_size, false);
} else { } else {
self->outgoing[0] = NULL; self->outgoing[0] = NULL;
self->outgoing[1] = NULL; self->outgoing[1] = NULL;
} }
self->max_packet_size = max_packet_size;
bleio_characteristic_set_observer(self->characteristic, self); bleio_characteristic_set_observer(self->characteristic, self);
} }
@ -128,7 +129,7 @@ mp_int_t common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self
// Copy received data. // Copy received data.
// Get packet length, which is in first two bytes of packet. // Get packet length, which is in first two bytes of packet.
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));
mp_int_t ret; mp_int_t ret;
if (packet_length > len) { if (packet_length > len) {
@ -136,7 +137,7 @@ mp_int_t common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self
ret = len - packet_length; ret = len - packet_length;
// Discard the packet if it's too large. Don't fill data. // Discard the packet if it's too large. Don't fill data.
while (packet_length--) { while (packet_length--) {
(void) ringbuf_get(&self->ringbuf); (void)ringbuf_get(&self->ringbuf);
} }
} else { } else {
// Read as much as possible, but might be shorter than len. // Read as much as possible, but might be shorter than len.
@ -147,7 +148,7 @@ mp_int_t common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self
return ret; return ret;
} }
mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len, uint8_t* header, size_t header_len) { mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len, uint8_t *header, size_t header_len) {
if (self->outgoing[0] == NULL) { if (self->outgoing[0] == NULL) {
mp_raise_bleio_BluetoothError(translate("Writes not supported on Characteristic")); mp_raise_bleio_BluetoothError(translate("Writes not supported on Characteristic"));
} }
@ -174,7 +175,7 @@ mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, u
size_t num_bytes_written = 0; size_t num_bytes_written = 0;
uint8_t* pending = self->outgoing[self->pending_index]; uint8_t *pending = self->outgoing[self->pending_index];
if (self->pending_size == 0) { if (self->pending_size == 0) {
memcpy(pending, header, header_len); memcpy(pending, header, header_len);
@ -213,7 +214,7 @@ mp_int_t common_hal_bleio_packet_buffer_get_incoming_packet_length(bleio_packet_
bleio_connection_internal_t *connection = bleio_conn_handle_to_connection(self->conn_handle); bleio_connection_internal_t *connection = bleio_conn_handle_to_connection(self->conn_handle);
if (connection) { if (connection) {
return MIN(common_hal_bleio_connection_get_max_packet_length(connection), return MIN(common_hal_bleio_connection_get_max_packet_length(connection),
self->characteristic->max_length); self->characteristic->max_length);
} }
} }
// There's no current connection, so we don't know the MTU, and // There's no current connection, so we don't know the MTU, and
@ -243,7 +244,8 @@ mp_int_t common_hal_bleio_packet_buffer_get_outgoing_packet_length(bleio_packet_
if (self->conn_handle != BLE_CONN_HANDLE_INVALID) { if (self->conn_handle != BLE_CONN_HANDLE_INVALID) {
bleio_connection_internal_t *connection = bleio_conn_handle_to_connection(self->conn_handle); bleio_connection_internal_t *connection = bleio_conn_handle_to_connection(self->conn_handle);
if (connection) { if (connection) {
return MIN(common_hal_bleio_connection_get_max_packet_length(connection), return MIN(MIN(common_hal_bleio_connection_get_max_packet_length(connection),
self->max_packet_size),
self->characteristic->max_length); self->characteristic->max_length);
} }
} }
@ -251,7 +253,7 @@ mp_int_t common_hal_bleio_packet_buffer_get_outgoing_packet_length(bleio_packet_
// we can't tell what the largest outgoing packet length would be. // we can't tell what the largest outgoing packet length would be.
return -1; return -1;
} }
return self->characteristic->max_length; return MIN(self->characteristic->max_length, self->max_packet_size);
} }
bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self) { bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self) {

View file

@ -37,11 +37,12 @@ typedef struct {
ringbuf_t ringbuf; ringbuf_t ringbuf;
// Two outgoing buffers to alternate between. One will be queued for transmission by the SD and // Two outgoing buffers to alternate between. One will be queued for transmission by the SD and
// the other is waiting to be queued and can be extended. // the other is waiting to be queued and can be extended.
uint8_t* outgoing[2]; uint8_t *outgoing[2];
volatile uint16_t pending_size; volatile uint16_t pending_size;
// We remember the conn_handle so we can do a NOTIFY/INDICATE to a client. // We remember the conn_handle so we can do a NOTIFY/INDICATE to a client.
// We can find out the conn_handle on a Characteristic write or a CCCD write (but not a read). // We can find out the conn_handle on a Characteristic write or a CCCD write (but not a read).
volatile uint16_t conn_handle; volatile uint16_t conn_handle;
uint16_t max_packet_size;
uint8_t pending_index; uint8_t pending_index;
uint8_t write_type; uint8_t write_type;
bool client; bool client;

View file

@ -32,7 +32,7 @@
#include "shared-bindings/_bleio/Service.h" #include "shared-bindings/_bleio/Service.h"
#include "shared-bindings/_bleio/Adapter.h" #include "shared-bindings/_bleio/Adapter.h"
uint32_t _common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, bool is_secondary, mp_obj_list_t * characteristic_list) { uint32_t _common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, bool is_secondary, mp_obj_list_t *characteristic_list) {
self->uuid = uuid; self->uuid = uuid;
self->characteristic_list = characteristic_list; self->characteristic_list = characteristic_list;
self->is_remote = false; self->is_remote = false;
@ -52,7 +52,7 @@ uint32_t _common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uu
void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, bool is_secondary) { void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, bool is_secondary) {
if (_common_hal_bleio_service_construct(self, uuid, is_secondary, if (_common_hal_bleio_service_construct(self, uuid, is_secondary,
mp_obj_new_list(0, NULL)) != 0) { mp_obj_new_list(0, NULL)) != 0) {
mp_raise_RuntimeError(translate("Failed to add service")); mp_raise_RuntimeError(translate("Failed to add service"));
} }
} }
@ -83,8 +83,8 @@ bool common_hal_bleio_service_get_is_secondary(bleio_service_obj_t *self) {
} }
void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self,
bleio_characteristic_obj_t *characteristic, bleio_characteristic_obj_t *characteristic,
mp_buffer_info_t *initial_value_bufinfo) { mp_buffer_info_t *initial_value_bufinfo) {
if (self->handle != common_hal_bleio_adapter_obj.last_added_service_handle) { if (self->handle != common_hal_bleio_adapter_obj.last_added_service_handle) {
mp_raise_bleio_BluetoothError( mp_raise_bleio_BluetoothError(

View file

@ -46,7 +46,7 @@ typedef struct bleio_service_obj {
// Range of attribute handles of this service. // Range of attribute handles of this service.
uint16_t start_handle; uint16_t start_handle;
uint16_t end_handle; uint16_t end_handle;
struct bleio_service_obj* next; struct bleio_service_obj *next;
} bleio_service_obj_t; } bleio_service_obj_t;
void bleio_service_from_connection(bleio_service_obj_t *self, mp_obj_t connection); void bleio_service_from_connection(bleio_service_obj_t *self, mp_obj_t connection);

View file

@ -60,7 +60,7 @@ void common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[1
memcpy(uuid128, self->uuid128, 16); memcpy(uuid128, self->uuid128, 16);
} }
void common_hal_bleio_uuid_pack_into(bleio_uuid_obj_t *self, uint8_t* buf) { void common_hal_bleio_uuid_pack_into(bleio_uuid_obj_t *self, uint8_t *buf) {
if (self->size == 16) { if (self->size == 16) {
buf[0] = self->uuid16 & 0xff; buf[0] = self->uuid16 & 0xff;
buf[1] = self->uuid16 >> 8; buf[1] = self->uuid16 >> 8;

View file

@ -33,17 +33,17 @@
// Types returned by attribute table lookups. These are UUIDs. // Types returned by attribute table lookups. These are UUIDs.
typedef enum { typedef enum {
BLE_UUID_UNKNOWN = 0x0000, BLE_UUID_UNKNOWN = 0x0000,
BLE_UUID_SERVICE_PRIMARY = 0x2800, BLE_UUID_SERVICE_PRIMARY = 0x2800,
BLE_UUID_SERVICE_SECONDARY = 0x2801, BLE_UUID_SERVICE_SECONDARY = 0x2801,
BLE_UUID_SERVICE_INCLUDE = 0x2802, // not yet implemented by us BLE_UUID_SERVICE_INCLUDE = 0x2802,// not yet implemented by us
BLE_UUID_CHARACTERISTIC = 0x2803, BLE_UUID_CHARACTERISTIC = 0x2803,
BLE_UUID_CHAR_EXTENDED_PROPS = 0x2900, // not yet implemented by us BLE_UUID_CHAR_EXTENDED_PROPS = 0x2900,// not yet implemented by us
BLE_UUID_CHAR_USER_DESC = 0x2901, // not yet implemented by us BLE_UUID_CHAR_USER_DESC = 0x2901,// not yet implemented by us
BLE_UUID_CCCD = 0x2902, BLE_UUID_CCCD = 0x2902,
BLE_UUID_SCCD = 0x2903, // not yet implemented by us BLE_UUID_SCCD = 0x2903,// not yet implemented by us
BLE_UUID_CHAR_PRESENTATION_FMT = 0x2904, // not yet implemented by us BLE_UUID_CHAR_PRESENTATION_FMT = 0x2904, // not yet implemented by us
BLE_UUID_CHAR_AGGREGATE_FMT = 0x2905, // not yet implemented by us BLE_UUID_CHAR_AGGREGATE_FMT = 0x2905,// not yet implemented by us
} ble_standard_uuid; } ble_standard_uuid;
typedef struct { typedef struct {

View file

@ -78,7 +78,7 @@ void bleio_reset() {
bleio_set_adapter(mp_const_none); bleio_set_adapter(mp_const_none);
//FIX bonding_reset(); // FIX bonding_reset();
supervisor_start_bluetooth(); supervisor_start_bluetooth();
} }

View file

@ -47,7 +47,7 @@ typedef struct {
// 20 bytes max (23 - 3). // 20 bytes max (23 - 3).
#define GATT_MAX_DATA_LENGTH (BT_ATT_DEFAULT_LE_MTU - 3) #define GATT_MAX_DATA_LENGTH (BT_ATT_DEFAULT_LE_MTU - 3)
//FIX // FIX
#define BLE_GATT_HANDLE_INVALID 0x0000 #define BLE_GATT_HANDLE_INVALID 0x0000
#define BLE_CONN_HANDLE_INVALID 0xFFFF #define BLE_CONN_HANDLE_INVALID 0xFFFF
#define BLE_GATTS_FIX_ATTR_LEN_MAX (510) /**< Maximum length for fixed length Attribute Values. */ #define BLE_GATTS_FIX_ATTR_LEN_MAX (510) /**< Maximum length for fixed length Attribute Values. */

View file

@ -24,8 +24,8 @@
#include "att.h" #include "att.h"
// Zephyr include files to define HCI communication values and structs. // Zephyr include files to define HCI communication values and structs.
//#include "hci_include/hci.h" // #include "hci_include/hci.h"
//#include "hci_include/hci_err.h" // #include "hci_include/hci_err.h"
#include "hci_include/l2cap_internal.h" #include "hci_include/l2cap_internal.h"
#include "py/obj.h" #include "py/obj.h"
@ -44,7 +44,7 @@ STATIC unsigned long timeout = 5000;
STATIC volatile bool confirm; STATIC volatile bool confirm;
STATIC uint16_t long_write_handle = BLE_GATT_HANDLE_INVALID; STATIC uint16_t long_write_handle = BLE_GATT_HANDLE_INVALID;
STATIC uint8_t* long_write_value = NULL; STATIC uint8_t *long_write_value = NULL;
STATIC uint16_t long_write_value_length = 0; STATIC uint16_t long_write_value_length = 0;
// When we send a request, fill this struct with info about the expected response. // When we send a request, fill this struct with info about the expected response.
@ -52,7 +52,7 @@ STATIC uint16_t long_write_value_length = 0;
STATIC struct { STATIC struct {
uint16_t conn_handle; // Expected handle. uint16_t conn_handle; // Expected handle.
uint8_t opcode; // Expected RSP opcode. uint8_t opcode; // Expected RSP opcode.
uint8_t* buffer; // Pointer to response packet uint8_t *buffer; // Pointer to response packet
uint8_t length; // Length of response packet. uint8_t length; // Length of response packet.
} expected_rsp; } expected_rsp;
@ -88,7 +88,7 @@ STATIC uint8_t bleio_properties_to_ble_spec_properties(uint8_t bleio_properties)
return ble_spec_properties; return ble_spec_properties;
} }
//FIX not currently used; reenable when used. // FIX not currently used; reenable when used.
#if 0 #if 0
STATIC uint8_t ble_spec_properties_to_bleio_properties(uint8_t ble_spec_properties) { STATIC uint8_t ble_spec_properties_to_bleio_properties(uint8_t ble_spec_properties) {
uint8_t bleio_properties = 0; uint8_t bleio_properties = 0;
@ -120,20 +120,19 @@ STATIC void send_error(uint16_t conn_handle, uint8_t opcode, uint16_t handle, ui
struct bt_att_hdr h; struct bt_att_hdr h;
struct bt_att_error_rsp r; struct bt_att_error_rsp r;
} rsp = { { } rsp = { {
.code = BT_ATT_OP_ERROR_RSP, .code = BT_ATT_OP_ERROR_RSP,
}, { }, {
.request = opcode, .request = opcode,
} }};
};
hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, sizeof(rsp), (uint8_t *) &rsp); hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, sizeof(rsp), (uint8_t *)&rsp);
} }
STATIC void send_req(uint16_t conn_handle, size_t request_length, uint8_t* request_buffer) { STATIC void send_req(uint16_t conn_handle, size_t request_length, uint8_t *request_buffer) {
hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, request_length, request_buffer); hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, request_length, request_buffer);
} }
STATIC int send_req_wait_for_rsp(uint16_t conn_handle, size_t request_length, uint8_t* request_buffer, uint8_t response_buffer[]) { STATIC int send_req_wait_for_rsp(uint16_t conn_handle, size_t request_length, uint8_t *request_buffer, uint8_t response_buffer[]) {
// We expect a particular kind of response after this request. // We expect a particular kind of response after this request.
expected_rsp.conn_handle = conn_handle; expected_rsp.conn_handle = conn_handle;
// The response opcode is the request opcode + 1. // The response opcode is the request opcode + 1.
@ -192,9 +191,9 @@ void bleio_att_reset(void) {
} }
bool att_connect_to_address(bt_addr_le_t *addr) { bool att_connect_to_address(bt_addr_le_t *addr) {
//FIX // FIX
if (hci_le_create_conn(0x0060, 0x0030, 0x00, addr, 0x00, if (hci_le_create_conn(0x0060, 0x0030, 0x00, addr, 0x00,
0x0006, 0x000c, 0x0000, 0x00c8, 0x0004, 0x0006) != 0) { 0x0006, 0x000c, 0x0000, 0x00c8, 0x0004, 0x0006) != 0) {
return false; return false;
} }
@ -229,7 +228,7 @@ bool att_disconnect(uint16_t conn_handle) {
return !att_handle_is_connected(conn_handle); return !att_handle_is_connected(conn_handle);
} }
//FIX // FIX
// STATIC bool discover_services(uint16_t conn_handle, BLERemoteDevice* device, const char* serviceUuidFilter) { // STATIC bool discover_services(uint16_t conn_handle, BLERemoteDevice* device, const char* serviceUuidFilter) {
// uint16_t reqStart_handle = 0x0001; // uint16_t reqStart_handle = 0x0001;
// uint16_t reqEnd_handle = 0xffff; // uint16_t reqEnd_handle = 0xffff;
@ -406,7 +405,7 @@ bool att_disconnect(uint16_t conn_handle) {
// return true; // return true;
// } // }
bool att_discover_attributes(bt_addr_le_t *addr, const char* service_uuid_filter) { bool att_discover_attributes(bt_addr_le_t *addr, const char *service_uuid_filter) {
uint16_t conn_handle = att_conn_handle(addr); uint16_t conn_handle = att_conn_handle(addr);
if (conn_handle == 0xffff) { if (conn_handle == 0xffff) {
return false; return false;
@ -418,7 +417,7 @@ bool att_discover_attributes(bt_addr_le_t *addr, const char* service_uuid_filter
} }
// find the device entry for the peeer // find the device entry for the peeer
//FIX BLERemoteDevice* device = NULL; // FIX BLERemoteDevice* device = NULL;
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
// if (bleio_connections[i].conn_handle == conn_handle) { // if (bleio_connections[i].conn_handle == conn_handle) {
@ -454,7 +453,7 @@ bool att_discover_attributes(bt_addr_le_t *addr, const char* service_uuid_filter
} }
// discover services // discover services
//FIX // FIX
// if (!att_discover_services(conn_handle, device, service_uuid_filter)) { // if (!att_discover_services(conn_handle, device, service_uuid_filter)) {
// return false; // return false;
// } // }
@ -481,10 +480,10 @@ void att_set_timeout(unsigned long timeout_in) {
} }
void att_add_connection(uint16_t handle, uint8_t role, bt_addr_le_t *peer_addr, uint16_t interval, uint16_t latency, uint16_t supervision_timeout, uint8_t master_clock_accuracy) { void att_add_connection(uint16_t handle, uint8_t role, bt_addr_le_t *peer_addr, uint16_t interval, uint16_t latency, uint16_t supervision_timeout, uint8_t master_clock_accuracy) {
(void) interval; (void)interval;
(void) latency; (void)latency;
(void) supervision_timeout; (void)supervision_timeout;
(void) master_clock_accuracy; (void)master_clock_accuracy;
int peer_index = -1; int peer_index = -1;
@ -508,7 +507,7 @@ void att_add_connection(uint16_t handle, uint8_t role, bt_addr_le_t *peer_addr,
void att_remove_connection(uint16_t conn_handle, uint8_t reason) { void att_remove_connection(uint16_t conn_handle, uint8_t reason) {
(void) reason; (void)reason;
int peer_index = -1; int peer_index = -1;
int peer_count = 0; int peer_count = 0;
@ -580,7 +579,7 @@ bool att_is_connected(void) {
} }
bool att_address_is_connected(bt_addr_le_t *addr) { bool att_address_is_connected(bt_addr_le_t *addr) {
return (att_conn_handle(addr) != 0xffff); return att_conn_handle(addr) != 0xffff;
} }
bool att_handle_is_connected(uint16_t handle) { bool att_handle_is_connected(uint16_t handle) {
@ -624,10 +623,10 @@ bool att_disconnect_all(void) {
bleio_connections[i].mtu = BT_ATT_DEFAULT_LE_MTU; bleio_connections[i].mtu = BT_ATT_DEFAULT_LE_MTU;
} }
return (num_disconnects > 0); return num_disconnects > 0;
} }
bool att_notify(uint16_t handle, const uint8_t* value, int length) { bool att_notify(uint16_t handle, const uint8_t *value, int length) {
int num_notifications = 0; int num_notifications = 0;
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
@ -643,20 +642,21 @@ bool att_notify(uint16_t handle, const uint8_t* value, int length) {
size_t allowed_length = MIN((uint16_t)(bleio_connections[i].mtu - sizeof(notify_t)), (uint16_t)length); size_t allowed_length = MIN((uint16_t)(bleio_connections[i].mtu - sizeof(notify_t)), (uint16_t)length);
uint8_t notify_bytes[sizeof(notify_t) + allowed_length]; uint8_t notify_bytes[sizeof(notify_t) + allowed_length];
notify_t *notify = (notify_t *) notify_bytes; notify_t *notify = (notify_t *)notify_bytes;
notify->hdr.code = BT_ATT_OP_NOTIFY;; notify->hdr.code = BT_ATT_OP_NOTIFY;
;
notify->ntf.handle = handle; notify->ntf.handle = handle;
memcpy(notify->ntf.value, value, allowed_length); memcpy(notify->ntf.value, value, allowed_length);
hci_send_acl_pkt(bleio_connections[i].conn_handle, BT_L2CAP_CID_ATT, hci_send_acl_pkt(bleio_connections[i].conn_handle, BT_L2CAP_CID_ATT,
sizeof(notify_bytes), notify_bytes); sizeof(notify_bytes), notify_bytes);
num_notifications++; num_notifications++;
} }
return (num_notifications > 0); return num_notifications > 0;
} }
bool att_indicate(uint16_t handle, const uint8_t* value, int length) { bool att_indicate(uint16_t handle, const uint8_t *value, int length) {
int num_indications = 0; int num_indications = 0;
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
@ -672,15 +672,16 @@ bool att_indicate(uint16_t handle, const uint8_t* value, int length) {
size_t allowed_length = MIN((uint16_t)(bleio_connections[i].mtu - sizeof(indicate_t)), (uint16_t)length); size_t allowed_length = MIN((uint16_t)(bleio_connections[i].mtu - sizeof(indicate_t)), (uint16_t)length);
uint8_t indicate_bytes[sizeof(indicate_t) + allowed_length]; uint8_t indicate_bytes[sizeof(indicate_t) + allowed_length];
indicate_t *indicate = (indicate_t *) indicate_bytes; indicate_t *indicate = (indicate_t *)indicate_bytes;
indicate->hdr.code = BT_ATT_OP_INDICATE;; indicate->hdr.code = BT_ATT_OP_INDICATE;
;
indicate->ind.handle = handle; indicate->ind.handle = handle;
memcpy(indicate->ind.value, value, allowed_length); memcpy(indicate->ind.value, value, allowed_length);
confirm = false; confirm = false;
hci_send_acl_pkt(bleio_connections[i].conn_handle, BT_L2CAP_CID_ATT, hci_send_acl_pkt(bleio_connections[i].conn_handle, BT_L2CAP_CID_ATT,
sizeof(indicate_bytes), indicate_bytes); sizeof(indicate_bytes), indicate_bytes);
while (!confirm) { while (!confirm) {
// RUN_BACKGROUND_TASKS includes hci_poll_for_incoming_pkt(); // RUN_BACKGROUND_TASKS includes hci_poll_for_incoming_pkt();
@ -694,11 +695,11 @@ bool att_indicate(uint16_t handle, const uint8_t* value, int length) {
num_indications++; num_indications++;
} }
return (num_indications > 0); return num_indications > 0;
} }
STATIC void process_error(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) { STATIC void process_error(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
struct bt_att_error_rsp *rsp = (struct bt_att_error_rsp *) data; struct bt_att_error_rsp *rsp = (struct bt_att_error_rsp *)data;
if (dlen != sizeof(struct bt_att_error_rsp)) { if (dlen != sizeof(struct bt_att_error_rsp)) {
// Incorrect size; ignore. // Incorrect size; ignore.
@ -714,7 +715,7 @@ STATIC void process_error(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
} }
STATIC void process_mtu_req(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) { STATIC void process_mtu_req(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
struct bt_att_exchange_mtu_req *req = (struct bt_att_exchange_mtu_req *) data; struct bt_att_exchange_mtu_req *req = (struct bt_att_exchange_mtu_req *)data;
if (dlen != sizeof(struct bt_att_exchange_mtu_req)) { if (dlen != sizeof(struct bt_att_exchange_mtu_req)) {
send_error(conn_handle, BT_ATT_OP_MTU_REQ, BLE_GATT_HANDLE_INVALID, BT_ATT_ERR_INVALID_PDU); send_error(conn_handle, BT_ATT_OP_MTU_REQ, BLE_GATT_HANDLE_INVALID, BT_ATT_ERR_INVALID_PDU);
@ -738,17 +739,16 @@ STATIC void process_mtu_req(uint16_t conn_handle, uint8_t dlen, uint8_t data[])
struct bt_att_hdr h; struct bt_att_hdr h;
struct bt_att_exchange_mtu_rsp r; struct bt_att_exchange_mtu_rsp r;
} rsp = { { } rsp = { {
.code = BT_ATT_OP_MTU_RSP, .code = BT_ATT_OP_MTU_RSP,
}, { }, {
.mtu = mtu, .mtu = mtu,
} }};
};
hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, sizeof(rsp), (uint8_t *) &rsp); hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, sizeof(rsp), (uint8_t *)&rsp);
} }
STATIC void process_mtu_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) { STATIC void process_mtu_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
struct bt_att_exchange_mtu_rsp *rsp = (struct bt_att_exchange_mtu_rsp *) data; struct bt_att_exchange_mtu_rsp *rsp = (struct bt_att_exchange_mtu_rsp *)data;
if (dlen != sizeof(struct bt_att_exchange_mtu_rsp)) { if (dlen != sizeof(struct bt_att_exchange_mtu_rsp)) {
return; return;
@ -765,7 +765,7 @@ STATIC void process_mtu_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[])
} }
STATIC void process_find_info_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) { STATIC void process_find_info_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) {
struct bt_att_find_info_req *req = (struct bt_att_find_info_req *) data; struct bt_att_find_info_req *req = (struct bt_att_find_info_req *)data;
if (dlen != sizeof(struct bt_att_find_info_req)) { if (dlen != sizeof(struct bt_att_find_info_req)) {
send_error(conn_handle, BT_ATT_OP_FIND_INFO_REQ, req->start_handle, BT_ATT_ERR_INVALID_PDU); send_error(conn_handle, BT_ATT_OP_FIND_INFO_REQ, req->start_handle, BT_ATT_ERR_INVALID_PDU);
@ -778,7 +778,7 @@ STATIC void process_find_info_req(uint16_t conn_handle, uint16_t mtu, uint8_t dl
} rsp_t; } rsp_t;
uint8_t rsp_bytes[mtu]; uint8_t rsp_bytes[mtu];
rsp_t *rsp = (rsp_t *) rsp_bytes; rsp_t *rsp = (rsp_t *)rsp_bytes;
rsp->h.code = BT_ATT_OP_FIND_INFO_RSP; rsp->h.code = BT_ATT_OP_FIND_INFO_RSP;
// Keeps track of total length of the response. // Keeps track of total length of the response.
@ -832,20 +832,20 @@ STATIC void process_find_info_req(uint16_t conn_handle, uint16_t mtu, uint8_t dl
} }
if (sizeof_uuid == 2) { if (sizeof_uuid == 2) {
struct bt_att_info_16 *info_16 = (struct bt_att_info_16 *) &rsp_bytes[rsp_length]; struct bt_att_info_16 *info_16 = (struct bt_att_info_16 *)&rsp_bytes[rsp_length];
info_16->handle = handle; info_16->handle = handle;
info_16->uuid = common_hal_bleio_uuid_get_uuid16(uuid); info_16->uuid = common_hal_bleio_uuid_get_uuid16(uuid);
rsp_length += sizeof(struct bt_att_info_16); rsp_length += sizeof(struct bt_att_info_16);
} else { } else {
struct bt_att_info_128 *info_128 = (struct bt_att_info_128 *) &rsp_bytes[rsp_length]; struct bt_att_info_128 *info_128 = (struct bt_att_info_128 *)&rsp_bytes[rsp_length];
info_128->handle = handle; info_128->handle = handle;
common_hal_bleio_uuid_get_uuid128(uuid, info_128->uuid); common_hal_bleio_uuid_get_uuid128(uuid, info_128->uuid);
rsp_length += sizeof(struct bt_att_info_128); rsp_length += sizeof(struct bt_att_info_128);
} }
no_data =false; no_data = false;
} // end for } // end for
@ -861,14 +861,13 @@ int att_find_info_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_
struct bt_att_hdr h; struct bt_att_hdr h;
struct bt_att_find_info_req r; struct bt_att_find_info_req r;
} req = { { } req = { {
.code = BT_ATT_OP_FIND_INFO_REQ, .code = BT_ATT_OP_FIND_INFO_REQ,
}, { }, {
.start_handle = start_handle, .start_handle = start_handle,
.end_handle = end_handle, .end_handle = end_handle,
} }};
};
return send_req_wait_for_rsp(conn_handle, sizeof(req), (uint8_t *) &req, response_buffer); return send_req_wait_for_rsp(conn_handle, sizeof(req), (uint8_t *)&req, response_buffer);
} }
STATIC void process_find_info_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) { STATIC void process_find_info_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
@ -880,7 +879,7 @@ STATIC void process_find_info_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t da
} }
STATIC void process_find_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) { STATIC void process_find_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) {
struct bt_att_find_type_req *req = (struct bt_att_find_type_req *) data; struct bt_att_find_type_req *req = (struct bt_att_find_type_req *)data;
if (dlen < sizeof(struct bt_att_find_type_req)) { if (dlen < sizeof(struct bt_att_find_type_req)) {
send_error(conn_handle, BT_ATT_OP_FIND_TYPE_RSP, req->start_handle, BT_ATT_ERR_INVALID_PDU); send_error(conn_handle, BT_ATT_OP_FIND_TYPE_RSP, req->start_handle, BT_ATT_ERR_INVALID_PDU);
@ -893,7 +892,7 @@ STATIC void process_find_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dl
response[0] = BT_ATT_OP_FIND_TYPE_RSP; response[0] = BT_ATT_OP_FIND_TYPE_RSP;
response_length = 1; response_length = 1;
//FIX // FIX
// if (find_type_req->type == BLE_UUID_SERVICE_PRIMARY) { // if (find_type_req->type == BLE_UUID_SERVICE_PRIMARY) {
// for (uint16_t i = (find_type_req->start_handle - 1); i < GATT.attributeCount() && i <= (find_type_req->end_handle - 1); i++) { // for (uint16_t i = (find_type_req->start_handle - 1); i < GATT.attributeCount() && i <= (find_type_req->end_handle - 1); i++) {
// BLELocalAttribute* attribute = GATT.attribute(i); // BLELocalAttribute* attribute = GATT.attribute(i);
@ -926,7 +925,7 @@ STATIC void process_find_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dl
} }
void process_read_group_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) { void process_read_group_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) {
struct bt_att_read_group_req *req = (struct bt_att_read_group_req *) data; struct bt_att_read_group_req *req = (struct bt_att_read_group_req *)data;
uint16_t type_uuid = req->uuid[0] | (req->uuid[1] << 8); uint16_t type_uuid = req->uuid[0] | (req->uuid[1] << 8);
// We only support returning services for BT_ATT_OP_READ_GROUP_REQ, which is typically used // We only support returning services for BT_ATT_OP_READ_GROUP_REQ, which is typically used
@ -944,7 +943,7 @@ void process_read_group_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, ui
} rsp_t; } rsp_t;
uint8_t rsp_bytes[mtu]; uint8_t rsp_bytes[mtu];
rsp_t *rsp = (rsp_t *) rsp_bytes; rsp_t *rsp = (rsp_t *)rsp_bytes;
rsp->h.code = BT_ATT_OP_READ_GROUP_RSP; rsp->h.code = BT_ATT_OP_READ_GROUP_RSP;
rsp->r.len = 0; rsp->r.len = 0;
@ -991,7 +990,7 @@ void process_read_group_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, ui
// There may be multiple chunks in this transmission. // There may be multiple chunks in this transmission.
rsp->r.len = data_length; rsp->r.len = data_length;
struct bt_att_group_data *group_data = (struct bt_att_group_data *) &rsp_bytes[rsp_length]; struct bt_att_group_data *group_data = (struct bt_att_group_data *)&rsp_bytes[rsp_length];
group_data->start_handle = service->start_handle; group_data->start_handle = service->start_handle;
group_data->end_handle = service->end_handle; group_data->end_handle = service->end_handle;
@ -1017,7 +1016,7 @@ int att_read_group_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end
} req_t; } req_t;
uint8_t req_bytes[sizeof(req_t) + sizeof(uuid)]; uint8_t req_bytes[sizeof(req_t) + sizeof(uuid)];
req_t *req = (req_t *) req_bytes; req_t *req = (req_t *)req_bytes;
req->h.code = BT_ATT_OP_READ_GROUP_REQ; req->h.code = BT_ATT_OP_READ_GROUP_REQ;
req->r.start_handle = start_handle; req->r.start_handle = start_handle;
@ -1047,7 +1046,7 @@ STATIC void process_read_or_read_blob_req(uint16_t conn_handle, uint16_t mtu, ui
return; return;
} }
struct bt_att_read_req *req = (struct bt_att_read_req *) data; struct bt_att_read_req *req = (struct bt_att_read_req *)data;
handle = req->handle; handle = req->handle;
response_opcode = BT_ATT_OP_READ_RSP; response_opcode = BT_ATT_OP_READ_RSP;
@ -1057,7 +1056,7 @@ STATIC void process_read_or_read_blob_req(uint16_t conn_handle, uint16_t mtu, ui
return; return;
} }
struct bt_att_read_blob_req *req = (struct bt_att_read_blob_req *) data; struct bt_att_read_blob_req *req = (struct bt_att_read_blob_req *)data;
handle = req->handle; handle = req->handle;
offset = req->offset; offset = req->offset;
response_opcode = BT_ATT_OP_READ_BLOB_RSP; response_opcode = BT_ATT_OP_READ_BLOB_RSP;
@ -1077,7 +1076,7 @@ STATIC void process_read_or_read_blob_req(uint16_t conn_handle, uint16_t mtu, ui
} rsp_t; } rsp_t;
uint8_t rsp_bytes[mtu]; uint8_t rsp_bytes[mtu];
rsp_t *rsp = (rsp_t *) rsp_bytes; rsp_t *rsp = (rsp_t *)rsp_bytes;
rsp->h.code = response_opcode; rsp->h.code = response_opcode;
// Keeps track of total length of the response. // Keeps track of total length of the response.
@ -1105,7 +1104,7 @@ STATIC void process_read_or_read_blob_req(uint16_t conn_handle, uint16_t mtu, ui
return; return;
} }
characteristic_declaration_t *char_decl = (characteristic_declaration_t *) rsp->r.value; characteristic_declaration_t *char_decl = (characteristic_declaration_t *)rsp->r.value;
// Convert from the bleio properties bit values to the BLE spec properties bit values. // Convert from the bleio properties bit values to the BLE spec properties bit values.
// They are not the same :(. // They are not the same :(.
@ -1160,7 +1159,7 @@ STATIC void process_read_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[])
} }
STATIC void process_read_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) { STATIC void process_read_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) {
struct bt_att_read_type_req *req = (struct bt_att_read_type_req *) data; struct bt_att_read_type_req *req = (struct bt_att_read_type_req *)data;
uint16_t type_uuid = req->uuid[0] | (req->uuid[1] << 8); uint16_t type_uuid = req->uuid[0] | (req->uuid[1] << 8);
if (dlen != sizeof(struct bt_att_read_type_req) + sizeof(type_uuid)) { if (dlen != sizeof(struct bt_att_read_type_req) + sizeof(type_uuid)) {
@ -1174,7 +1173,7 @@ STATIC void process_read_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dl
} rsp_t; } rsp_t;
uint8_t rsp_bytes[mtu]; uint8_t rsp_bytes[mtu];
rsp_t *rsp = (rsp_t *) rsp_bytes; rsp_t *rsp = (rsp_t *)rsp_bytes;
rsp->h.code = BT_ATT_OP_READ_TYPE_RSP; rsp->h.code = BT_ATT_OP_READ_TYPE_RSP;
rsp->r.len = 0; rsp->r.len = 0;
@ -1233,11 +1232,11 @@ STATIC void process_read_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dl
// There may be multiple chunks in this transmission. // There may be multiple chunks in this transmission.
rsp->r.len = data_length; rsp->r.len = data_length;
struct bt_att_data *att_data = (struct bt_att_data *) &rsp_bytes[rsp_length]; struct bt_att_data *att_data = (struct bt_att_data *)&rsp_bytes[rsp_length];
att_data->handle = characteristic->decl_handle; att_data->handle = characteristic->decl_handle;
characteristic_declaration_t *char_decl = (characteristic_declaration_t *) att_data->value; characteristic_declaration_t *char_decl = (characteristic_declaration_t *)att_data->value;
// Convert from the bleio properties bit values to the BLE spec properties bit values. // Convert from the bleio properties bit values to the BLE spec properties bit values.
// They are not the same :(. // They are not the same :(.
@ -1255,7 +1254,7 @@ STATIC void process_read_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dl
// See if request is for a descriptor value with a 16-bit UUID, such as the CCCD. // See if request is for a descriptor value with a 16-bit UUID, such as the CCCD.
bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(attribute_obj); bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(attribute_obj);
if (bleio_uuid_get_uuid16_or_unknown(descriptor->uuid) == type_uuid) { if (bleio_uuid_get_uuid16_or_unknown(descriptor->uuid) == type_uuid) {
struct bt_att_data *att_data = (struct bt_att_data *) &rsp_bytes[rsp_length]; struct bt_att_data *att_data = (struct bt_att_data *)&rsp_bytes[rsp_length];
att_data->handle = handle; att_data->handle = handle;
@ -1277,7 +1276,7 @@ STATIC void process_read_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dl
bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj); bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj);
if (bleio_uuid_get_uuid16_or_unknown(characteristic->uuid) == type_uuid) { if (bleio_uuid_get_uuid16_or_unknown(characteristic->uuid) == type_uuid) {
struct bt_att_data *att_data = (struct bt_att_data *) &rsp_bytes[rsp_length]; struct bt_att_data *att_data = (struct bt_att_data *)&rsp_bytes[rsp_length];
att_data->handle = handle; att_data->handle = handle;
@ -1299,7 +1298,7 @@ STATIC void process_read_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dl
if (no_data) { if (no_data) {
send_error(conn_handle, BT_ATT_OP_READ_TYPE_REQ, send_error(conn_handle, BT_ATT_OP_READ_TYPE_REQ,
req->start_handle, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND); req->start_handle, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
} else { } else {
hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, rsp_length, rsp_bytes); hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, rsp_length, rsp_bytes);
} }
@ -1312,7 +1311,7 @@ int att_read_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_
} req_t; } req_t;
uint8_t req_bytes[sizeof(req_t) + sizeof(type)]; uint8_t req_bytes[sizeof(req_t) + sizeof(type)];
req_t *req = (req_t *) req_bytes; req_t *req = (req_t *)req_bytes;
req->h.code = BT_ATT_OP_READ_TYPE_REQ; req->h.code = BT_ATT_OP_READ_TYPE_REQ;
req->r.start_handle = start_handle; req->r.start_handle = start_handle;
@ -1334,7 +1333,7 @@ STATIC void process_read_type_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t da
// Handles BT_ATT_OP_WRITE_REQ or BT_ATT_OP_WRITE_ // Handles BT_ATT_OP_WRITE_REQ or BT_ATT_OP_WRITE_
STATIC void process_write_req_or_cmd(uint16_t conn_handle, uint16_t mtu, uint8_t op, uint8_t dlen, uint8_t data[]) { STATIC void process_write_req_or_cmd(uint16_t conn_handle, uint16_t mtu, uint8_t op, uint8_t dlen, uint8_t data[]) {
// struct bt_att_write_cmd is identical, so don't bother to split code paths based on opcode. // struct bt_att_write_cmd is identical, so don't bother to split code paths based on opcode.
struct bt_att_write_req *req = (struct bt_att_write_req *) data; struct bt_att_write_req *req = (struct bt_att_write_req *)data;
bool with_response = (op == BT_ATT_OP_WRITE_REQ); bool with_response = (op == BT_ATT_OP_WRITE_REQ);
@ -1397,7 +1396,7 @@ STATIC void process_write_req_or_cmd(uint16_t conn_handle, uint16_t mtu, uint8_t
.code = BT_ATT_OP_WRITE_RSP, .code = BT_ATT_OP_WRITE_RSP,
}; };
hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, sizeof(rsp), (uint8_t *) &rsp); hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, sizeof(rsp), (uint8_t *)&rsp);
} }
} }
@ -1410,7 +1409,7 @@ STATIC void process_write_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[]
} }
STATIC void process_prepare_write_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) { STATIC void process_prepare_write_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) {
struct bt_att_prepare_write_req *req = (struct bt_att_prepare_write_req *) data; struct bt_att_prepare_write_req *req = (struct bt_att_prepare_write_req *)data;
if (dlen < sizeof(struct bt_att_prepare_write_req)) { if (dlen < sizeof(struct bt_att_prepare_write_req)) {
send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, BLE_GATT_HANDLE_INVALID, BT_ATT_ERR_INVALID_PDU); send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, BLE_GATT_HANDLE_INVALID, BT_ATT_ERR_INVALID_PDU);
@ -1419,7 +1418,7 @@ STATIC void process_prepare_write_req(uint16_t conn_handle, uint16_t mtu, uint8_
uint16_t handle = req->handle; uint16_t handle = req->handle;
uint16_t offset = req->offset; uint16_t offset = req->offset;
(void) offset; (void)offset;
if (handle > bleio_adapter_max_attribute_handle(&common_hal_bleio_adapter_obj)) { if (handle > bleio_adapter_max_attribute_handle(&common_hal_bleio_adapter_obj)) {
send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, handle, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND); send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, handle, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
@ -1433,7 +1432,7 @@ STATIC void process_prepare_write_req(uint16_t conn_handle, uint16_t mtu, uint8_
return; return;
} }
bleio_characteristic_obj_t* characteristic = MP_OBJ_TO_PTR(attribute); bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute);
if (handle != characteristic->handle) { if (handle != characteristic->handle) {
send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, handle, BT_ATT_ERR_ATTRIBUTE_NOT_LONG); send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, handle, BT_ATT_ERR_ATTRIBUTE_NOT_LONG);
@ -1445,7 +1444,7 @@ STATIC void process_prepare_write_req(uint16_t conn_handle, uint16_t mtu, uint8_
return; return;
} }
//FIX if (long_write_handle == BLE_GATT_HANDLE_INVALID) // FIX if (long_write_handle == BLE_GATT_HANDLE_INVALID)
// int valueSize = characteristic->valueSize(); // int valueSize = characteristic->valueSize();
// long_write_value = (uint8_t*)realloc(long_write_value, valueSize); // long_write_value = (uint8_t*)realloc(long_write_value, valueSize);
@ -1480,7 +1479,7 @@ STATIC void process_prepare_write_req(uint16_t conn_handle, uint16_t mtu, uint8_
} }
STATIC void process_exec_write_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) { STATIC void process_exec_write_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) {
struct bt_att_exec_write_req *req = (struct bt_att_exec_write_req *) data; struct bt_att_exec_write_req *req = (struct bt_att_exec_write_req *)data;
if (dlen != sizeof(struct bt_att_exec_write_req)) { if (dlen != sizeof(struct bt_att_exec_write_req)) {
send_error(conn_handle, BT_ATT_OP_EXEC_WRITE_REQ, BLE_GATT_HANDLE_INVALID, BT_ATT_ERR_INVALID_PDU); send_error(conn_handle, BT_ATT_OP_EXEC_WRITE_REQ, BLE_GATT_HANDLE_INVALID, BT_ATT_ERR_INVALID_PDU);
@ -1488,11 +1487,11 @@ STATIC void process_exec_write_req(uint16_t conn_handle, uint16_t mtu, uint8_t d
} }
if (long_write_handle && (req->flags & 0x01)) { if (long_write_handle && (req->flags & 0x01)) {
//FIX BLELocalCharacteristic* characteristic = (BLELocalCharacteristic*)GATT.attribute(long_write_handle - 1); // FIX BLELocalCharacteristic* characteristic = (BLELocalCharacteristic*)GATT.attribute(long_write_handle - 1);
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
if (bleio_connections[i].conn_handle == conn_handle) { if (bleio_connections[i].conn_handle == conn_handle) {
//FIX characteristic->writeValue(BLEDevice(bleio_connections[i].address_type, bleio_connections[i].address), long_write_value, long_write_value_length); // FIX characteristic->writeValue(BLEDevice(bleio_connections[i].address_type, bleio_connections[i].address), long_write_value, long_write_value_length);
break; break;
} }
} }
@ -1516,16 +1515,16 @@ STATIC void process_notify_or_indicate(uint16_t conn_handle, uint8_t opcode, uin
} }
// struct bt_att_notify and bt_att_indicate are identical. // struct bt_att_notify and bt_att_indicate are identical.
//FIXunused struct bt_att_notify *req = (struct bt_att_notify *) data; // FIXunused struct bt_att_notify *req = (struct bt_att_notify *) data;
//FIXunused uint8_t handle = req->handle; // FIXunused uint8_t handle = req->handle;
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
if (bleio_connections[i].conn_handle != conn_handle) { if (bleio_connections[i].conn_handle != conn_handle) {
continue; continue;
} }
//FIX BLERemoteDevice* device = bleio_connections[i].device; // FIX BLERemoteDevice* device = bleio_connections[i].device;
// if (!device) { // if (!device) {
// break; // break;
@ -1562,9 +1561,9 @@ STATIC void process_notify_or_indicate(uint16_t conn_handle, uint8_t opcode, uin
} }
STATIC void process_confirm(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) { STATIC void process_confirm(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
(void) conn_handle; (void)conn_handle;
(void) dlen; (void)dlen;
(void) data; (void)data;
confirm = true; confirm = true;
} }
@ -1574,7 +1573,7 @@ bool att_exchange_mtu(uint16_t conn_handle) {
struct bt_att_exchange_mtu_req req = { struct bt_att_exchange_mtu_req req = {
.mtu = max_mtu, .mtu = max_mtu,
}; };
return send_req_wait_for_rsp(conn_handle, sizeof(req), (uint8_t *) &req, response_buffer); return send_req_wait_for_rsp(conn_handle, sizeof(req), (uint8_t *)&req, response_buffer);
} }
int att_read_req(uint16_t conn_handle, uint16_t handle, uint8_t response_buffer[]) { int att_read_req(uint16_t conn_handle, uint16_t handle, uint8_t response_buffer[]) {
@ -1582,23 +1581,22 @@ int att_read_req(uint16_t conn_handle, uint16_t handle, uint8_t response_buffer[
struct bt_att_hdr h; struct bt_att_hdr h;
struct bt_att_read_req r; struct bt_att_read_req r;
} req = { { } req = { {
.code = BT_ATT_OP_READ_REQ, .code = BT_ATT_OP_READ_REQ,
}, { }, {
.handle = handle, .handle = handle,
} }};
};
return send_req_wait_for_rsp(conn_handle, sizeof(req), (uint8_t *) &req, response_buffer); return send_req_wait_for_rsp(conn_handle, sizeof(req), (uint8_t *)&req, response_buffer);
} }
int att_write_req(uint16_t conn_handle, uint16_t handle, const uint8_t* data, uint8_t data_len, uint8_t response_buffer[]) { int att_write_req(uint16_t conn_handle, uint16_t handle, const uint8_t *data, uint8_t data_len, uint8_t response_buffer[]) {
typedef struct __packed { typedef struct __packed {
struct bt_att_hdr h; struct bt_att_hdr h;
struct bt_att_write_req r; struct bt_att_write_req r;
} req_t; } req_t;
uint8_t req_bytes[sizeof(req_t) + data_len]; uint8_t req_bytes[sizeof(req_t) + data_len];
req_t *req = (req_t *) req_bytes; req_t *req = (req_t *)req_bytes;
req->h.code = BT_ATT_OP_WRITE_REQ; req->h.code = BT_ATT_OP_WRITE_REQ;
req->r.handle = handle; req->r.handle = handle;
memcpy(req->r.value, data, data_len); memcpy(req->r.value, data, data_len);
@ -1606,14 +1604,14 @@ int att_write_req(uint16_t conn_handle, uint16_t handle, const uint8_t* data, ui
return send_req_wait_for_rsp(conn_handle, sizeof(req_bytes), req_bytes, response_buffer); return send_req_wait_for_rsp(conn_handle, sizeof(req_bytes), req_bytes, response_buffer);
} }
void att_write_cmd(uint16_t conn_handle, uint16_t handle, const uint8_t* data, uint8_t data_len) { void att_write_cmd(uint16_t conn_handle, uint16_t handle, const uint8_t *data, uint8_t data_len) {
typedef struct __packed { typedef struct __packed {
struct bt_att_hdr h; struct bt_att_hdr h;
struct bt_att_write_cmd r; struct bt_att_write_cmd r;
} cmd_t; } cmd_t;
uint8_t cmd_bytes[sizeof(cmd_t) + data_len]; uint8_t cmd_bytes[sizeof(cmd_t) + data_len];
cmd_t *cmd = (cmd_t *) cmd_bytes; cmd_t *cmd = (cmd_t *)cmd_bytes;
cmd->h.code = BT_ATT_OP_WRITE_CMD; cmd->h.code = BT_ATT_OP_WRITE_CMD;
cmd->r.handle = handle; cmd->r.handle = handle;
memcpy(cmd->r.value, data, data_len); memcpy(cmd->r.value, data, data_len);
@ -1715,7 +1713,7 @@ void att_process_data(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
} }
} }
//FIX Do we need all of these? // FIX Do we need all of these?
void check_att_err(uint8_t err) { void check_att_err(uint8_t err) {
const compressed_string_t *msg = NULL; const compressed_string_t *msg = NULL;
switch (err) { switch (err) {

View file

@ -32,19 +32,19 @@
void bleio_att_reset(void); void bleio_att_reset(void);
//FIX void att_set_event_handler(BLEDeviceEvent event, BLEDeviceEventHandler eventHandler); // FIX void att_set_event_handler(BLEDeviceEvent event, BLEDeviceEventHandler eventHandler);
bool att_address_is_connected(bt_addr_le_t *addr); bool att_address_is_connected(bt_addr_le_t *addr);
bool att_connect_to_address(bt_addr_le_t *addr); bool att_connect_to_address(bt_addr_le_t *addr);
bool att_disconnect(uint16_t conn_handle); bool att_disconnect(uint16_t conn_handle);
bool att_disconnect_all(void); bool att_disconnect_all(void);
bool att_discover_attributes(bt_addr_le_t *addr, const char* service_uuid_filter); bool att_discover_attributes(bt_addr_le_t *addr, const char *service_uuid_filter);
bool att_exchange_mtu(uint16_t conn_handle); bool att_exchange_mtu(uint16_t conn_handle);
bool att_handle_is_connected(uint16_t handle); bool att_handle_is_connected(uint16_t handle);
bool att_indicate(uint16_t handle, const uint8_t* value, int length); bool att_indicate(uint16_t handle, const uint8_t *value, int length);
bool att_is_connected(void); bool att_is_connected(void);
bool att_notify(uint16_t handle, const uint8_t* value, int length); bool att_notify(uint16_t handle, const uint8_t *value, int length);
int att_read_req(uint16_t conn_handle, uint16_t handle, uint8_t response_buffer[]); int att_read_req(uint16_t conn_handle, uint16_t handle, uint8_t response_buffer[]);
int att_write_req(uint16_t conn_handle, uint16_t handle, const uint8_t* data, uint8_t data_len, uint8_t response_buffer[]); int att_write_req(uint16_t conn_handle, uint16_t handle, const uint8_t *data, uint8_t data_len, uint8_t response_buffer[]);
uint16_t att_conn_handle(bt_addr_le_t *addr); uint16_t att_conn_handle(bt_addr_le_t *addr);
uint16_t att_mtu(uint16_t handle); uint16_t att_mtu(uint16_t handle);
void att_add_connection(uint16_t handle, uint8_t role, bt_addr_le_t *peer_addr, uint16_t interval, uint16_t latency, uint16_t supervision_timeout, uint8_t master_clock_accuracy); void att_add_connection(uint16_t handle, uint8_t role, bt_addr_le_t *peer_addr, uint16_t interval, uint16_t latency, uint16_t supervision_timeout, uint8_t master_clock_accuracy);
@ -52,6 +52,6 @@ void att_process_data(uint16_t conn_handle, uint8_t dlen, uint8_t data[]);
void att_remove_connection(uint16_t conn_handle, uint8_t reason); void att_remove_connection(uint16_t conn_handle, uint8_t reason);
void att_set_max_mtu(uint16_t max_mtu); void att_set_max_mtu(uint16_t max_mtu);
void att_set_timeout(unsigned long timeout); void att_set_timeout(unsigned long timeout);
void att_write_cmd(uint16_t conn_handle, uint16_t handle, const uint8_t* data, uint8_t data_len); void att_write_cmd(uint16_t conn_handle, uint16_t handle, const uint8_t *data, uint8_t data_len);
#endif // MICROPY_INCLUDED_DEVICES_BLE_HCI_COMMON_HAL_BLEIO_ATT_H #endif // MICROPY_INCLUDED_DEVICES_BLE_HCI_COMMON_HAL_BLEIO_ATT_H

View file

@ -27,7 +27,7 @@
#include <string.h> #include <string.h>
#include "py/mphal.h" //***************************** #include "py/mphal.h" // *****************************
#include "supervisor/shared/tick.h" #include "supervisor/shared/tick.h"
#include "shared-bindings/_bleio/__init__.h" #include "shared-bindings/_bleio/__init__.h"
#include "common-hal/_bleio/Adapter.h" #include "common-hal/_bleio/Adapter.h"
@ -63,8 +63,8 @@ typedef struct __attribute__ ((packed)) {
typedef struct __attribute__ ((packed)) { typedef struct __attribute__ ((packed)) {
uint8_t pkt_type; uint8_t pkt_type;
uint16_t handle : 12; uint16_t handle : 12;
uint8_t pb: 2; // Packet boundary flag: ACL_DATA_PB values. uint8_t pb : 2; // Packet boundary flag: ACL_DATA_PB values.
uint8_t bc: 2; // Broadcast flag: always 0b00 for BLE. uint8_t bc : 2; // Broadcast flag: always 0b00 for BLE.
uint16_t data_len; // length of data[] in this packet. uint16_t data_len; // length of data[] in this packet.
uint8_t data[]; uint8_t data[];
} h4_hci_acl_pkt_t; } h4_hci_acl_pkt_t;
@ -89,7 +89,7 @@ typedef struct __attribute__ ((packed)) {
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// Static storage: // Static storage:
//FIX size // FIX size
#define RX_BUFFER_SIZE (3 + 255) #define RX_BUFFER_SIZE (3 + 255)
#define ACL_DATA_BUFFER_SIZE (255) #define ACL_DATA_BUFFER_SIZE (255)
@ -107,7 +107,7 @@ STATIC bool cmd_response_received;
STATIC uint16_t cmd_response_opcode; STATIC uint16_t cmd_response_opcode;
STATIC uint8_t cmd_response_status; STATIC uint8_t cmd_response_status;
STATIC size_t cmd_response_len; STATIC size_t cmd_response_len;
STATIC uint8_t* cmd_response_data; STATIC uint8_t *cmd_response_data;
STATIC volatile bool hci_poll_in_progress = false; STATIC volatile bool hci_poll_in_progress = false;
@ -119,7 +119,7 @@ STATIC volatile bool hci_poll_in_progress = false;
#endif // HCI_DEBUG #endif // HCI_DEBUG
STATIC void process_acl_data_pkt(uint8_t pkt_len, uint8_t pkt_data[]) { STATIC void process_acl_data_pkt(uint8_t pkt_len, uint8_t pkt_data[]) {
h4_hci_acl_pkt_t *pkt = (h4_hci_acl_pkt_t*) pkt_data; h4_hci_acl_pkt_t *pkt = (h4_hci_acl_pkt_t *)pkt_data;
if (pkt->pb != ACL_DATA_PB_MIDDLE) { if (pkt->pb != ACL_DATA_PB_MIDDLE) {
// This is the start of a fragmented acl_data packet or is a full packet. // This is the start of a fragmented acl_data packet or is a full packet.
@ -132,7 +132,7 @@ STATIC void process_acl_data_pkt(uint8_t pkt_len, uint8_t pkt_data[]) {
acl_data_len += pkt->data_len; acl_data_len += pkt->data_len;
} }
acl_data_t *acl = (acl_data_t *) &acl_data_buffer; acl_data_t *acl = (acl_data_t *)&acl_data_buffer;
if (acl_data_len != sizeof(acl) + acl->acl_data_len) { if (acl_data_len != sizeof(acl) + acl->acl_data_len) {
// We don't have the full packet yet. // We don't have the full packet yet.
return; return;
@ -167,18 +167,17 @@ STATIC void process_num_comp_pkts(uint16_t handle, uint16_t num_pkts) {
} }
} }
STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt_data[]) STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt_data[]) {
{ h4_hci_evt_pkt_t *pkt = (h4_hci_evt_pkt_t *)pkt_data;
h4_hci_evt_pkt_t *pkt = (h4_hci_evt_pkt_t*) pkt_data;
switch (pkt->evt) { switch (pkt->evt) {
case BT_HCI_EVT_DISCONN_COMPLETE: { case BT_HCI_EVT_DISCONN_COMPLETE: {
struct bt_hci_evt_disconn_complete *disconn_complete = struct bt_hci_evt_disconn_complete *disconn_complete =
(struct bt_hci_evt_disconn_complete*) pkt->params; (struct bt_hci_evt_disconn_complete *)pkt->params;
(void) disconn_complete; (void)disconn_complete;
att_remove_connection(disconn_complete->handle, disconn_complete->reason); att_remove_connection(disconn_complete->handle, disconn_complete->reason);
//FIX L2CAPSignaling.removeConnection(disconn_complete->handle, disconn_complete->reason); // FIX L2CAPSignaling.removeConnection(disconn_complete->handle, disconn_complete->reason);
break; break;
} }
@ -188,7 +187,7 @@ STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt_data[])
struct bt_hci_evt_cc_status cc_status; struct bt_hci_evt_cc_status cc_status;
} __packed; } __packed;
struct cmd_complete_with_status *evt = (struct cmd_complete_with_status *) pkt->params; struct cmd_complete_with_status *evt = (struct cmd_complete_with_status *)pkt->params;
num_command_packets_allowed = evt->cmd_complete.ncmd; num_command_packets_allowed = evt->cmd_complete.ncmd;
@ -197,7 +196,7 @@ STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt_data[])
cmd_response_status = evt->cc_status.status; cmd_response_status = evt->cc_status.status;
// All the bytes following cmd_complete, -including- the status byte, which is // All the bytes following cmd_complete, -including- the status byte, which is
// included in all the _bt_hci_rp_* structs. // included in all the _bt_hci_rp_* structs.
cmd_response_data = (uint8_t *) &evt->cc_status; cmd_response_data = (uint8_t *)&evt->cc_status;
// Includes status byte. // Includes status byte.
cmd_response_len = pkt->param_len - sizeof_field(struct cmd_complete_with_status, cmd_complete); cmd_response_len = pkt->param_len - sizeof_field(struct cmd_complete_with_status, cmd_complete);
@ -205,7 +204,7 @@ STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt_data[])
} }
case BT_HCI_EVT_CMD_STATUS: { case BT_HCI_EVT_CMD_STATUS: {
struct bt_hci_evt_cmd_status *evt = (struct bt_hci_evt_cmd_status *) pkt->params; struct bt_hci_evt_cmd_status *evt = (struct bt_hci_evt_cmd_status *)pkt->params;
num_command_packets_allowed = evt->ncmd; num_command_packets_allowed = evt->ncmd;
@ -220,7 +219,7 @@ STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt_data[])
case BT_HCI_EVT_NUM_COMPLETED_PACKETS: { case BT_HCI_EVT_NUM_COMPLETED_PACKETS: {
struct bt_hci_evt_num_completed_packets *evt = struct bt_hci_evt_num_completed_packets *evt =
(struct bt_hci_evt_num_completed_packets *) pkt->params; (struct bt_hci_evt_num_completed_packets *)pkt->params;
// Start at zero-th pair: (conn handle, num completed packets). // Start at zero-th pair: (conn handle, num completed packets).
struct bt_hci_handle_count *handle_and_count = &(evt->h[0]); struct bt_hci_handle_count *handle_and_count = &(evt->h[0]);
@ -232,8 +231,8 @@ STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt_data[])
} }
case BT_HCI_EVT_LE_META_EVENT: { case BT_HCI_EVT_LE_META_EVENT: {
struct bt_hci_evt_le_meta_event *meta_evt = (struct bt_hci_evt_le_meta_event *) pkt->params; struct bt_hci_evt_le_meta_event *meta_evt = (struct bt_hci_evt_le_meta_event *)pkt->params;
uint8_t *le_evt = pkt->params + sizeof (struct bt_hci_evt_le_meta_event); uint8_t *le_evt = pkt->params + sizeof (struct bt_hci_evt_le_meta_event);
if (meta_evt->subevent == BT_HCI_EVT_LE_CONN_COMPLETE) { if (meta_evt->subevent == BT_HCI_EVT_LE_CONN_COMPLETE) {
// Advertising stops when connection occurs. // Advertising stops when connection occurs.
@ -243,7 +242,7 @@ STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt_data[])
bleio_adapter_advertising_was_stopped(&common_hal_bleio_adapter_obj); bleio_adapter_advertising_was_stopped(&common_hal_bleio_adapter_obj);
struct bt_hci_evt_le_conn_complete *le_conn_complete = struct bt_hci_evt_le_conn_complete *le_conn_complete =
(struct bt_hci_evt_le_conn_complete *) le_evt; (struct bt_hci_evt_le_conn_complete *)le_evt;
if (le_conn_complete->status == BT_HCI_ERR_SUCCESS) { if (le_conn_complete->status == BT_HCI_ERR_SUCCESS) {
att_add_connection( att_add_connection(
@ -258,9 +257,9 @@ STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt_data[])
} }
} else if (meta_evt->subevent == BT_HCI_EVT_LE_ADVERTISING_REPORT) { } else if (meta_evt->subevent == BT_HCI_EVT_LE_ADVERTISING_REPORT) {
struct bt_hci_evt_le_advertising_info *le_advertising_info = struct bt_hci_evt_le_advertising_info *le_advertising_info =
(struct bt_hci_evt_le_advertising_info *) le_evt; (struct bt_hci_evt_le_advertising_info *)le_evt;
if (le_advertising_info->evt_type == BT_HCI_ADV_DIRECT_IND) { if (le_advertising_info->evt_type == BT_HCI_ADV_DIRECT_IND) {
//FIX // FIX
// last byte is RSSI // last byte is RSSI
// GAP.handleLeAdvertisingReport(leAdvertisingReport->type, // GAP.handleLeAdvertisingReport(leAdvertisingReport->type,
// leAdvertisingReport->peerBdaddrType, // leAdvertisingReport->peerBdaddrType,
@ -275,9 +274,9 @@ STATIC void process_evt_pkt(size_t pkt_len, uint8_t pkt_data[])
} }
default: default:
#if HCI_DEBUG #if HCI_DEBUG
mp_printf(&mp_plat_print, "process_evt_pkt: Unknown event: %02x\n"); mp_printf(&mp_plat_print, "process_evt_pkt: Unknown event: %02x\n");
#endif #endif
break; break;
} }
} }
@ -333,7 +332,7 @@ hci_result_t hci_poll_for_incoming_pkt(void) {
case H4_ACL: case H4_ACL:
if (rx_idx >= sizeof(h4_hci_acl_pkt_t)) { if (rx_idx >= sizeof(h4_hci_acl_pkt_t)) {
const size_t total_len = const size_t total_len =
sizeof(h4_hci_acl_pkt_t) + ((h4_hci_acl_pkt_t *) rx_buffer)->data_len; sizeof(h4_hci_acl_pkt_t) + ((h4_hci_acl_pkt_t *)rx_buffer)->data_len;
if (rx_idx == total_len) { if (rx_idx == total_len) {
packet_is_complete = true; packet_is_complete = true;
} }
@ -346,7 +345,7 @@ hci_result_t hci_poll_for_incoming_pkt(void) {
case H4_EVT: case H4_EVT:
if (rx_idx >= sizeof(h4_hci_evt_pkt_t)) { if (rx_idx >= sizeof(h4_hci_evt_pkt_t)) {
const size_t total_len = const size_t total_len =
sizeof(h4_hci_evt_pkt_t) + ((h4_hci_evt_pkt_t *) rx_buffer)->param_len; sizeof(h4_hci_evt_pkt_t) + ((h4_hci_evt_pkt_t *)rx_buffer)->param_len;
if (rx_idx == total_len) { if (rx_idx == total_len) {
packet_is_complete = true; packet_is_complete = true;
} }
@ -374,23 +373,23 @@ hci_result_t hci_poll_for_incoming_pkt(void) {
switch (rx_buffer[0]) { switch (rx_buffer[0]) {
case H4_ACL: case H4_ACL:
#if HCI_DEBUG #if HCI_DEBUG
dump_acl_pkt(false, pkt_len, rx_buffer); dump_acl_pkt(false, pkt_len, rx_buffer);
#endif #endif
process_acl_data_pkt(pkt_len, rx_buffer); process_acl_data_pkt(pkt_len, rx_buffer);
break; break;
case H4_EVT: case H4_EVT:
#if HCI_DEBUG #if HCI_DEBUG
dump_evt_pkt(false, pkt_len, rx_buffer); dump_evt_pkt(false, pkt_len, rx_buffer);
#endif #endif
process_evt_pkt(pkt_len, rx_buffer); process_evt_pkt(pkt_len, rx_buffer);
break; break;
default: default:
#if HCI_DEBUG #if HCI_DEBUG
mp_printf(&mp_plat_print, "Unknown HCI packet type: %d\n", rx_buffer[0]); mp_printf(&mp_plat_print, "Unknown HCI packet type: %d\n", rx_buffer[0]);
#endif #endif
break; break;
} }
@ -425,21 +424,21 @@ STATIC hci_result_t write_pkt(uint8_t *buffer, size_t len) {
return HCI_OK; return HCI_OK;
} }
STATIC hci_result_t send_command(uint16_t opcode, uint8_t params_len, void* params) { STATIC hci_result_t send_command(uint16_t opcode, uint8_t params_len, void *params) {
uint8_t cmd_pkt_len = sizeof(h4_hci_cmd_pkt_t) + params_len; uint8_t cmd_pkt_len = sizeof(h4_hci_cmd_pkt_t) + params_len;
uint8_t tx_buffer[cmd_pkt_len]; uint8_t tx_buffer[cmd_pkt_len];
// cmd header is at the beginning of tx_buffer // cmd header is at the beginning of tx_buffer
h4_hci_cmd_pkt_t *cmd_pkt = (h4_hci_cmd_pkt_t *) tx_buffer; h4_hci_cmd_pkt_t *cmd_pkt = (h4_hci_cmd_pkt_t *)tx_buffer;
cmd_pkt->pkt_type = H4_CMD; cmd_pkt->pkt_type = H4_CMD;
cmd_pkt->opcode = opcode; cmd_pkt->opcode = opcode;
cmd_pkt->param_len = params_len; cmd_pkt->param_len = params_len;
memcpy(cmd_pkt->params, params, params_len); memcpy(cmd_pkt->params, params, params_len);
#if HCI_DEBUG #if HCI_DEBUG
dump_cmd_pkt(true, sizeof(tx_buffer), tx_buffer); dump_cmd_pkt(true, sizeof(tx_buffer), tx_buffer);
#endif #endif
int result = write_pkt(tx_buffer, cmd_pkt_len); int result = write_pkt(tx_buffer, cmd_pkt_len);
if (result != HCI_OK) { if (result != HCI_OK) {
@ -478,8 +477,8 @@ hci_result_t hci_send_acl_pkt(uint16_t handle, uint8_t cid, uint16_t data_len, u
const size_t buf_len = sizeof(h4_hci_acl_pkt_t) + sizeof(acl_data_t) + data_len; const size_t buf_len = sizeof(h4_hci_acl_pkt_t) + sizeof(acl_data_t) + data_len;
uint8_t tx_buffer[buf_len]; uint8_t tx_buffer[buf_len];
h4_hci_acl_pkt_t *acl_pkt = (h4_hci_acl_pkt_t *) tx_buffer; h4_hci_acl_pkt_t *acl_pkt = (h4_hci_acl_pkt_t *)tx_buffer;
acl_data_t *acl_data = (acl_data_t *) acl_pkt->data; acl_data_t *acl_data = (acl_data_t *)acl_pkt->data;
acl_pkt->pkt_type = H4_ACL; acl_pkt->pkt_type = H4_ACL;
acl_pkt->handle = handle; acl_pkt->handle = handle;
acl_pkt->pb = ACL_DATA_PB_FIRST_FLUSH; acl_pkt->pb = ACL_DATA_PB_FIRST_FLUSH;
@ -490,9 +489,9 @@ hci_result_t hci_send_acl_pkt(uint16_t handle, uint8_t cid, uint16_t data_len, u
memcpy(&acl_data->acl_data, data, data_len); memcpy(&acl_data->acl_data, data, data_len);
#if HCI_DEBUG #if HCI_DEBUG
dump_acl_pkt(true, buf_len, tx_buffer); dump_acl_pkt(true, buf_len, tx_buffer);
#endif #endif
pending_pkt++; pending_pkt++;
@ -512,7 +511,7 @@ hci_result_t hci_read_local_version(uint8_t *hci_version, uint16_t *hci_revision
hci_result_t result = send_command(BT_HCI_OP_READ_LOCAL_VERSION_INFO, 0, NULL); hci_result_t result = send_command(BT_HCI_OP_READ_LOCAL_VERSION_INFO, 0, NULL);
if (result == HCI_OK) { if (result == HCI_OK) {
struct bt_hci_rp_read_local_version_info *response = struct bt_hci_rp_read_local_version_info *response =
(struct bt_hci_rp_read_local_version_info *) cmd_response_data; (struct bt_hci_rp_read_local_version_info *)cmd_response_data;
*hci_version = response->hci_version; *hci_version = response->hci_version;
*hci_revision = response->hci_revision; *hci_revision = response->hci_revision;
*lmp_version = response->lmp_version; *lmp_version = response->lmp_version;
@ -526,7 +525,7 @@ hci_result_t hci_read_local_version(uint8_t *hci_version, uint16_t *hci_revision
hci_result_t hci_read_bd_addr(bt_addr_t *addr) { hci_result_t hci_read_bd_addr(bt_addr_t *addr) {
int result = send_command(BT_HCI_OP_READ_BD_ADDR, 0, NULL); int result = send_command(BT_HCI_OP_READ_BD_ADDR, 0, NULL);
if (result == HCI_OK) { if (result == HCI_OK) {
struct bt_hci_rp_read_bd_addr *response = (struct bt_hci_rp_read_bd_addr *) cmd_response_data; struct bt_hci_rp_read_bd_addr *response = (struct bt_hci_rp_read_bd_addr *)cmd_response_data;
memcpy(addr->val, response->bdaddr.val, sizeof_field(bt_addr_t, val)); memcpy(addr->val, response->bdaddr.val, sizeof_field(bt_addr_t, val));
} }
@ -536,7 +535,7 @@ hci_result_t hci_read_bd_addr(bt_addr_t *addr) {
hci_result_t hci_read_rssi(uint16_t handle, int *rssi) { hci_result_t hci_read_rssi(uint16_t handle, int *rssi) {
int result = send_command(BT_HCI_OP_READ_RSSI, sizeof(handle), &handle); int result = send_command(BT_HCI_OP_READ_RSSI, sizeof(handle), &handle);
if (result == HCI_OK) { if (result == HCI_OK) {
struct bt_hci_rp_read_rssi *response = (struct bt_hci_rp_read_rssi *) cmd_response_data; struct bt_hci_rp_read_rssi *response = (struct bt_hci_rp_read_rssi *)cmd_response_data;
*rssi = response->rssi; *rssi = response->rssi;
} }
@ -551,7 +550,7 @@ hci_result_t hci_le_read_buffer_size(uint16_t *le_max_len, uint8_t *le_max_num)
int result = send_command(BT_HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); int result = send_command(BT_HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
if (result == HCI_OK) { if (result == HCI_OK) {
struct bt_hci_rp_le_read_buffer_size *response = struct bt_hci_rp_le_read_buffer_size *response =
(struct bt_hci_rp_le_read_buffer_size *) cmd_response_data; (struct bt_hci_rp_le_read_buffer_size *)cmd_response_data;
*le_max_len = response->le_max_len; *le_max_len = response->le_max_len;
*le_max_num = response->le_max_num; *le_max_num = response->le_max_num;
} }
@ -563,7 +562,7 @@ hci_result_t hci_read_buffer_size(uint16_t *acl_max_len, uint8_t *sco_max_len, u
int result = send_command(BT_HCI_OP_READ_BUFFER_SIZE, 0, NULL); int result = send_command(BT_HCI_OP_READ_BUFFER_SIZE, 0, NULL);
if (result == HCI_OK) { if (result == HCI_OK) {
struct bt_hci_rp_read_buffer_size *response = struct bt_hci_rp_read_buffer_size *response =
(struct bt_hci_rp_read_buffer_size *) cmd_response_data; (struct bt_hci_rp_read_buffer_size *)cmd_response_data;
*acl_max_len = response->acl_max_len; *acl_max_len = response->acl_max_len;
*sco_max_len = response->sco_max_len; *sco_max_len = response->sco_max_len;
*acl_max_num = response->acl_max_num; *acl_max_num = response->acl_max_num;
@ -608,10 +607,10 @@ hci_result_t hci_le_set_extended_advertising_parameters(uint8_t handle, uint16_t
.scan_req_notify_enable = scan_req_notify_enable, .scan_req_notify_enable = scan_req_notify_enable,
}; };
// Assumes little-endian. // Assumes little-endian.
memcpy(params.prim_min_interval, (void *) &prim_min_interval, memcpy(params.prim_min_interval, (void *)&prim_min_interval,
sizeof_field(struct bt_hci_cp_le_set_ext_adv_param, prim_min_interval)); sizeof_field(struct bt_hci_cp_le_set_ext_adv_param, prim_min_interval));
memcpy(params.prim_max_interval, (void *) &prim_max_interval, memcpy(params.prim_max_interval, (void *)&prim_max_interval,
sizeof_field(struct bt_hci_cp_le_set_ext_adv_param, prim_max_interval)); sizeof_field(struct bt_hci_cp_le_set_ext_adv_param, prim_max_interval));
memcpy(params.peer_addr.a.val, peer_addr->a.val, sizeof_field(bt_addr_le_t, a.val)); memcpy(params.peer_addr.a.val, peer_addr->a.val, sizeof_field(bt_addr_le_t, a.val));
return send_command(BT_HCI_OP_LE_SET_EXT_ADV_PARAM, sizeof(params), &params); return send_command(BT_HCI_OP_LE_SET_EXT_ADV_PARAM, sizeof(params), &params);
} }
@ -620,7 +619,7 @@ hci_result_t hci_le_read_maximum_advertising_data_length(uint16_t *max_adv_data_
int result = send_command(BT_HCI_OP_LE_READ_MAX_ADV_DATA_LEN, 0, NULL); int result = send_command(BT_HCI_OP_LE_READ_MAX_ADV_DATA_LEN, 0, NULL);
if (result == HCI_OK) { if (result == HCI_OK) {
struct bt_hci_rp_le_read_max_adv_data_len *response = struct bt_hci_rp_le_read_max_adv_data_len *response =
(struct bt_hci_rp_le_read_max_adv_data_len *) cmd_response_data; (struct bt_hci_rp_le_read_max_adv_data_len *)cmd_response_data;
*max_adv_data_len = response->max_adv_data_len; *max_adv_data_len = response->max_adv_data_len;
} }
@ -631,9 +630,9 @@ hci_result_t hci_le_read_local_supported_features(uint8_t features[8]) {
int result = send_command(BT_HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL); int result = send_command(BT_HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
if (result == HCI_OK) { if (result == HCI_OK) {
struct bt_hci_rp_le_read_local_features *response = struct bt_hci_rp_le_read_local_features *response =
(struct bt_hci_rp_le_read_local_features *) cmd_response_data; (struct bt_hci_rp_le_read_local_features *)cmd_response_data;
memcpy(features, response->features, memcpy(features, response->features,
sizeof_field(struct bt_hci_rp_le_read_local_features, features)); sizeof_field(struct bt_hci_rp_le_read_local_features, features));
} }
return result; return result;
@ -685,7 +684,7 @@ hci_result_t hci_le_set_advertising_enable(uint8_t enable) {
hci_result_t hci_le_set_extended_advertising_enable(uint8_t enable, uint8_t set_num, uint8_t handle[], uint16_t duration[], uint8_t max_ext_adv_evts[]) { hci_result_t hci_le_set_extended_advertising_enable(uint8_t enable, uint8_t set_num, uint8_t handle[], uint16_t duration[], uint8_t max_ext_adv_evts[]) {
uint8_t params[sizeof(struct bt_hci_cp_le_set_ext_adv_enable) + uint8_t params[sizeof(struct bt_hci_cp_le_set_ext_adv_enable) +
set_num * (sizeof(struct bt_hci_ext_adv_set))]; set_num * (sizeof(struct bt_hci_ext_adv_set))];
struct bt_hci_cp_le_set_ext_adv_enable *params_p = (struct bt_hci_cp_le_set_ext_adv_enable *) &params; struct bt_hci_cp_le_set_ext_adv_enable *params_p = (struct bt_hci_cp_le_set_ext_adv_enable *)&params;
params_p->enable = enable; params_p->enable = enable;
params_p->set_num = set_num; params_p->set_num = set_num;
for (size_t i = 0; i < set_num; i++) { for (size_t i = 0; i < set_num; i++) {

View file

@ -26,248 +26,462 @@
// This file is #include'd in hci.c when HCI_DEBUG is non-zero. // This file is #include'd in hci.c when HCI_DEBUG is non-zero.
STATIC const char* att_opcode_name(uint16_t opcode) { STATIC const char *att_opcode_name(uint16_t opcode) {
switch (opcode) { switch (opcode) {
case BT_ATT_OP_ERROR_RSP: return "ERROR_RSP"; case BT_ATT_OP_ERROR_RSP:
case BT_ATT_OP_MTU_REQ: return "MTU_REQ"; return "ERROR_RSP";
case BT_ATT_OP_MTU_RSP: return "MTU_RSP"; case BT_ATT_OP_MTU_REQ:
case BT_ATT_OP_FIND_INFO_REQ: return "FIND_INFO_REQ"; return "MTU_REQ";
case BT_ATT_OP_FIND_INFO_RSP: return "FIND_INFO_RSP"; case BT_ATT_OP_MTU_RSP:
case BT_ATT_OP_FIND_TYPE_REQ: return "FIND_TYPE_REQ"; return "MTU_RSP";
case BT_ATT_OP_FIND_TYPE_RSP: return "FIND_TYPE_RSP"; case BT_ATT_OP_FIND_INFO_REQ:
case BT_ATT_OP_READ_TYPE_REQ: return "READ_TYPE_REQ"; return "FIND_INFO_REQ";
case BT_ATT_OP_READ_TYPE_RSP: return "READ_TYPE_RSP"; case BT_ATT_OP_FIND_INFO_RSP:
case BT_ATT_OP_READ_REQ: return "READ_REQ"; return "FIND_INFO_RSP";
case BT_ATT_OP_READ_RSP: return "READ_RSP"; case BT_ATT_OP_FIND_TYPE_REQ:
case BT_ATT_OP_READ_BLOB_REQ: return "READ_BLOB_REQ"; return "FIND_TYPE_REQ";
case BT_ATT_OP_READ_BLOB_RSP: return "READ_BLOB_RSP"; case BT_ATT_OP_FIND_TYPE_RSP:
case BT_ATT_OP_READ_MULT_REQ: return "READ_MULT_REQ"; return "FIND_TYPE_RSP";
case BT_ATT_OP_READ_MULT_RSP: return "READ_MULT_RSP"; case BT_ATT_OP_READ_TYPE_REQ:
case BT_ATT_OP_READ_GROUP_REQ: return "READ_GROUP_REQ"; return "READ_TYPE_REQ";
case BT_ATT_OP_READ_GROUP_RSP: return "READ_GROUP_RSP"; case BT_ATT_OP_READ_TYPE_RSP:
case BT_ATT_OP_WRITE_REQ: return "WRITE_REQ"; return "READ_TYPE_RSP";
case BT_ATT_OP_WRITE_RSP: return "WRITE_RSP"; case BT_ATT_OP_READ_REQ:
case BT_ATT_OP_PREPARE_WRITE_REQ: return "PREPARE_WRITE_REQ"; return "READ_REQ";
case BT_ATT_OP_PREPARE_WRITE_RSP: return "PREPARE_WRITE_RSP"; case BT_ATT_OP_READ_RSP:
case BT_ATT_OP_EXEC_WRITE_REQ: return "EXEC_WRITE_REQ"; return "READ_RSP";
case BT_ATT_OP_EXEC_WRITE_RSP: return "EXEC_WRITE_RSP"; case BT_ATT_OP_READ_BLOB_REQ:
case BT_ATT_OP_NOTIFY: return "NOTIFY"; return "READ_BLOB_REQ";
case BT_ATT_OP_INDICATE: return "INDICATE"; case BT_ATT_OP_READ_BLOB_RSP:
case BT_ATT_OP_CONFIRM: return "CONFIRM"; return "READ_BLOB_RSP";
case BT_ATT_OP_READ_MULT_VL_REQ: return "READ_MULT_VL_REQ"; case BT_ATT_OP_READ_MULT_REQ:
case BT_ATT_OP_READ_MULT_VL_RSP: return "READ_MULT_VL_RSP"; return "READ_MULT_REQ";
case BT_ATT_OP_NOTIFY_MULT: return "NOTIFY_MULT"; case BT_ATT_OP_READ_MULT_RSP:
case BT_ATT_OP_WRITE_CMD: return "WRITE_CMD"; return "READ_MULT_RSP";
case BT_ATT_OP_SIGNED_WRITE_CMD: return "SIGNED_WRITE_CMD"; case BT_ATT_OP_READ_GROUP_REQ:
default: return ""; return "READ_GROUP_REQ";
case BT_ATT_OP_READ_GROUP_RSP:
return "READ_GROUP_RSP";
case BT_ATT_OP_WRITE_REQ:
return "WRITE_REQ";
case BT_ATT_OP_WRITE_RSP:
return "WRITE_RSP";
case BT_ATT_OP_PREPARE_WRITE_REQ:
return "PREPARE_WRITE_REQ";
case BT_ATT_OP_PREPARE_WRITE_RSP:
return "PREPARE_WRITE_RSP";
case BT_ATT_OP_EXEC_WRITE_REQ:
return "EXEC_WRITE_REQ";
case BT_ATT_OP_EXEC_WRITE_RSP:
return "EXEC_WRITE_RSP";
case BT_ATT_OP_NOTIFY:
return "NOTIFY";
case BT_ATT_OP_INDICATE:
return "INDICATE";
case BT_ATT_OP_CONFIRM:
return "CONFIRM";
case BT_ATT_OP_READ_MULT_VL_REQ:
return "READ_MULT_VL_REQ";
case BT_ATT_OP_READ_MULT_VL_RSP:
return "READ_MULT_VL_RSP";
case BT_ATT_OP_NOTIFY_MULT:
return "NOTIFY_MULT";
case BT_ATT_OP_WRITE_CMD:
return "WRITE_CMD";
case BT_ATT_OP_SIGNED_WRITE_CMD:
return "SIGNED_WRITE_CMD";
default:
return "";
} }
} }
STATIC const char* hci_evt_name(uint8_t evt) { STATIC const char *hci_evt_name(uint8_t evt) {
switch (evt) { switch (evt) {
case BT_HCI_EVT_UNKNOWN: return "UNKNOWN"; case BT_HCI_EVT_UNKNOWN:
case BT_HCI_EVT_VENDOR: return "VENDOR"; return "UNKNOWN";
case BT_HCI_EVT_INQUIRY_COMPLETE: return "INQUIRY_COMPLETE"; case BT_HCI_EVT_VENDOR:
case BT_HCI_EVT_CONN_COMPLETE: return "CONN_COMPLETE"; return "VENDOR";
case BT_HCI_EVT_CONN_REQUEST: return "CONN_REQUEST"; case BT_HCI_EVT_INQUIRY_COMPLETE:
case BT_HCI_EVT_DISCONN_COMPLETE: return "DISCONN_COMPLETE"; return "INQUIRY_COMPLETE";
case BT_HCI_EVT_AUTH_COMPLETE: return "AUTH_COMPLETE"; case BT_HCI_EVT_CONN_COMPLETE:
case BT_HCI_EVT_REMOTE_NAME_REQ_COMPLETE: return "REMOTE_NAME_REQ_COMPLETE"; return "CONN_COMPLETE";
case BT_HCI_EVT_ENCRYPT_CHANGE: return "ENCRYPT_CHANGE"; case BT_HCI_EVT_CONN_REQUEST:
case BT_HCI_EVT_REMOTE_FEATURES: return "REMOTE_FEATURES"; return "CONN_REQUEST";
case BT_HCI_EVT_REMOTE_VERSION_INFO: return "REMOTE_VERSION_INFO"; case BT_HCI_EVT_DISCONN_COMPLETE:
case BT_HCI_EVT_CMD_COMPLETE: return "CMD_COMPLETE"; return "DISCONN_COMPLETE";
case BT_HCI_EVT_CMD_STATUS: return "CMD_STATUS"; case BT_HCI_EVT_AUTH_COMPLETE:
case BT_HCI_EVT_ROLE_CHANGE: return "ROLE_CHANGE"; return "AUTH_COMPLETE";
case BT_HCI_EVT_NUM_COMPLETED_PACKETS: return "NUM_COMPLETED_PACKETS"; case BT_HCI_EVT_REMOTE_NAME_REQ_COMPLETE:
case BT_HCI_EVT_PIN_CODE_REQ: return "PIN_CODE_REQ"; return "REMOTE_NAME_REQ_COMPLETE";
case BT_HCI_EVT_LINK_KEY_REQ: return "LINK_KEY_REQ"; case BT_HCI_EVT_ENCRYPT_CHANGE:
case BT_HCI_EVT_LINK_KEY_NOTIFY: return "LINK_KEY_NOTIFY"; return "ENCRYPT_CHANGE";
case BT_HCI_EVT_DATA_BUF_OVERFLOW: return "DATA_BUF_OVERFLOW"; case BT_HCI_EVT_REMOTE_FEATURES:
case BT_HCI_EVT_INQUIRY_RESULT_WITH_RSSI: return "INQUIRY_RESULT_WITH_RSSI"; return "REMOTE_FEATURES";
case BT_HCI_EVT_REMOTE_EXT_FEATURES: return "REMOTE_EXT_FEATURES"; case BT_HCI_EVT_REMOTE_VERSION_INFO:
case BT_HCI_EVT_SYNC_CONN_COMPLETE: return "SYNC_CONN_COMPLETE"; return "REMOTE_VERSION_INFO";
case BT_HCI_EVT_EXTENDED_INQUIRY_RESULT: return "EXTENDED_INQUIRY_RESULT"; case BT_HCI_EVT_CMD_COMPLETE:
case BT_HCI_EVT_ENCRYPT_KEY_REFRESH_COMPLETE: return "ENCRYPT_KEY_REFRESH_COMPLETE"; return "CMD_COMPLETE";
case BT_HCI_EVT_IO_CAPA_REQ: return "IO_CAPA_REQ"; case BT_HCI_EVT_CMD_STATUS:
case BT_HCI_EVT_IO_CAPA_RESP: return "IO_CAPA_RESP"; return "CMD_STATUS";
case BT_HCI_EVT_USER_CONFIRM_REQ: return "USER_CONFIRM_REQ"; case BT_HCI_EVT_ROLE_CHANGE:
case BT_HCI_EVT_USER_PASSKEY_REQ: return "USER_PASSKEY_REQ"; return "ROLE_CHANGE";
case BT_HCI_EVT_SSP_COMPLETE: return "SSP_COMPLETE"; case BT_HCI_EVT_NUM_COMPLETED_PACKETS:
case BT_HCI_EVT_USER_PASSKEY_NOTIFY: return "USER_PASSKEY_NOTIFY"; return "NUM_COMPLETED_PACKETS";
case BT_HCI_EVT_LE_META_EVENT: return "LE_META_EVENT"; case BT_HCI_EVT_PIN_CODE_REQ:
case BT_HCI_EVT_AUTH_PAYLOAD_TIMEOUT_EXP: return "AUTH_PAYLOAD_TIMEOUT_EXP"; return "PIN_CODE_REQ";
default: return ""; case BT_HCI_EVT_LINK_KEY_REQ:
return "LINK_KEY_REQ";
case BT_HCI_EVT_LINK_KEY_NOTIFY:
return "LINK_KEY_NOTIFY";
case BT_HCI_EVT_DATA_BUF_OVERFLOW:
return "DATA_BUF_OVERFLOW";
case BT_HCI_EVT_INQUIRY_RESULT_WITH_RSSI:
return "INQUIRY_RESULT_WITH_RSSI";
case BT_HCI_EVT_REMOTE_EXT_FEATURES:
return "REMOTE_EXT_FEATURES";
case BT_HCI_EVT_SYNC_CONN_COMPLETE:
return "SYNC_CONN_COMPLETE";
case BT_HCI_EVT_EXTENDED_INQUIRY_RESULT:
return "EXTENDED_INQUIRY_RESULT";
case BT_HCI_EVT_ENCRYPT_KEY_REFRESH_COMPLETE:
return "ENCRYPT_KEY_REFRESH_COMPLETE";
case BT_HCI_EVT_IO_CAPA_REQ:
return "IO_CAPA_REQ";
case BT_HCI_EVT_IO_CAPA_RESP:
return "IO_CAPA_RESP";
case BT_HCI_EVT_USER_CONFIRM_REQ:
return "USER_CONFIRM_REQ";
case BT_HCI_EVT_USER_PASSKEY_REQ:
return "USER_PASSKEY_REQ";
case BT_HCI_EVT_SSP_COMPLETE:
return "SSP_COMPLETE";
case BT_HCI_EVT_USER_PASSKEY_NOTIFY:
return "USER_PASSKEY_NOTIFY";
case BT_HCI_EVT_LE_META_EVENT:
return "LE_META_EVENT";
case BT_HCI_EVT_AUTH_PAYLOAD_TIMEOUT_EXP:
return "AUTH_PAYLOAD_TIMEOUT_EXP";
default:
return "";
} }
} }
STATIC const char* hci_evt_le_name(uint8_t evt_le) { STATIC const char *hci_evt_le_name(uint8_t evt_le) {
switch (evt_le) { switch (evt_le) {
case BT_HCI_EVT_LE_CONN_COMPLETE: return "LE_CONN_COMPLETE"; case BT_HCI_EVT_LE_CONN_COMPLETE:
case BT_HCI_EVT_LE_ADVERTISING_REPORT: return "LE_ADVERTISING_REPORT"; return "LE_CONN_COMPLETE";
case BT_HCI_EVT_LE_CONN_UPDATE_COMPLETE: return "LE_CONN_UPDATE_COMPLETE"; case BT_HCI_EVT_LE_ADVERTISING_REPORT:
case BT_HCI_EVT_LE_LTK_REQUEST: return "LE_LTK_REQUEST"; return "LE_ADVERTISING_REPORT";
case BT_HCI_EVT_LE_CONN_PARAM_REQ: return "LE_CONN_PARAM_REQ"; case BT_HCI_EVT_LE_CONN_UPDATE_COMPLETE:
case BT_HCI_EVT_LE_DATA_LEN_CHANGE: return "LE_DATA_LEN_CHANGE"; return "LE_CONN_UPDATE_COMPLETE";
case BT_HCI_EVT_LE_P256_PUBLIC_KEY_COMPLETE: return "LE_P256_PUBLIC_KEY_COMPLETE"; case BT_HCI_EVT_LE_LTK_REQUEST:
case BT_HCI_EVT_LE_GENERATE_DHKEY_COMPLETE: return "LE_GENERATE_DHKEY_COMPLETE"; return "LE_LTK_REQUEST";
case BT_HCI_EVT_LE_ENH_CONN_COMPLETE: return "LE_ENH_CONN_COMPLETE"; case BT_HCI_EVT_LE_CONN_PARAM_REQ:
case BT_HCI_EVT_LE_DIRECT_ADV_REPORT: return "LE_DIRECT_ADV_REPORT"; return "LE_CONN_PARAM_REQ";
case BT_HCI_EVT_LE_PHY_UPDATE_COMPLETE: return "LE_PHY_UPDATE_COMPLETE"; case BT_HCI_EVT_LE_DATA_LEN_CHANGE:
case BT_HCI_EVT_LE_EXT_ADVERTISING_REPORT: return "LE_EXT_ADVERTISING_REPORT"; return "LE_DATA_LEN_CHANGE";
case BT_HCI_EVT_LE_PER_ADV_SYNC_ESTABLISHED: return "LE_PER_ADV_SYNC_ESTABLISHED"; case BT_HCI_EVT_LE_P256_PUBLIC_KEY_COMPLETE:
case BT_HCI_EVT_LE_PER_ADVERTISING_REPORT: return "LE_PER_ADVERTISING_REPORT"; return "LE_P256_PUBLIC_KEY_COMPLETE";
case BT_HCI_EVT_LE_PER_ADV_SYNC_LOST: return "LE_PER_ADV_SYNC_LOST"; case BT_HCI_EVT_LE_GENERATE_DHKEY_COMPLETE:
case BT_HCI_EVT_LE_SCAN_TIMEOUT: return "LE_SCAN_TIMEOUT"; return "LE_GENERATE_DHKEY_COMPLETE";
case BT_HCI_EVT_LE_ADV_SET_TERMINATED: return "LE_ADV_SET_TERMINATED"; case BT_HCI_EVT_LE_ENH_CONN_COMPLETE:
case BT_HCI_EVT_LE_SCAN_REQ_RECEIVED: return "LE_SCAN_REQ_RECEIVED"; return "LE_ENH_CONN_COMPLETE";
case BT_HCI_EVT_LE_CHAN_SEL_ALGO: return "LE_CHAN_SEL_ALGO"; case BT_HCI_EVT_LE_DIRECT_ADV_REPORT:
default: return ""; return "LE_DIRECT_ADV_REPORT";
case BT_HCI_EVT_LE_PHY_UPDATE_COMPLETE:
return "LE_PHY_UPDATE_COMPLETE";
case BT_HCI_EVT_LE_EXT_ADVERTISING_REPORT:
return "LE_EXT_ADVERTISING_REPORT";
case BT_HCI_EVT_LE_PER_ADV_SYNC_ESTABLISHED:
return "LE_PER_ADV_SYNC_ESTABLISHED";
case BT_HCI_EVT_LE_PER_ADVERTISING_REPORT:
return "LE_PER_ADVERTISING_REPORT";
case BT_HCI_EVT_LE_PER_ADV_SYNC_LOST:
return "LE_PER_ADV_SYNC_LOST";
case BT_HCI_EVT_LE_SCAN_TIMEOUT:
return "LE_SCAN_TIMEOUT";
case BT_HCI_EVT_LE_ADV_SET_TERMINATED:
return "LE_ADV_SET_TERMINATED";
case BT_HCI_EVT_LE_SCAN_REQ_RECEIVED:
return "LE_SCAN_REQ_RECEIVED";
case BT_HCI_EVT_LE_CHAN_SEL_ALGO:
return "LE_CHAN_SEL_ALGO";
default:
return "";
} }
} }
STATIC const char* hci_opcode_name(uint16_t opcode) { STATIC const char *hci_opcode_name(uint16_t opcode) {
switch (opcode) { switch (opcode) {
case BT_OP_NOP: return "NOP"; case BT_OP_NOP:
case BT_HCI_OP_INQUIRY: return "INQUIRY"; return "NOP";
case BT_HCI_OP_INQUIRY_CANCEL: return "INQUIRY_CANCEL"; case BT_HCI_OP_INQUIRY:
case BT_HCI_OP_CONNECT: return "CONNECT"; return "INQUIRY";
case BT_HCI_OP_DISCONNECT: return "DISCONNECT"; case BT_HCI_OP_INQUIRY_CANCEL:
case BT_HCI_OP_CONNECT_CANCEL: return "CONNECT_CANCEL"; return "INQUIRY_CANCEL";
case BT_HCI_OP_ACCEPT_CONN_REQ: return "ACCEPT_CONN_REQ"; case BT_HCI_OP_CONNECT:
case BT_HCI_OP_SETUP_SYNC_CONN: return "SETUP_SYNC_CONN"; return "CONNECT";
case BT_HCI_OP_ACCEPT_SYNC_CONN_REQ: return "ACCEPT_SYNC_CONN_REQ"; case BT_HCI_OP_DISCONNECT:
case BT_HCI_OP_REJECT_CONN_REQ: return "REJECT_CONN_REQ"; return "DISCONNECT";
case BT_HCI_OP_LINK_KEY_REPLY: return "LINK_KEY_REPLY"; case BT_HCI_OP_CONNECT_CANCEL:
case BT_HCI_OP_LINK_KEY_NEG_REPLY: return "LINK_KEY_NEG_REPLY"; return "CONNECT_CANCEL";
case BT_HCI_OP_PIN_CODE_REPLY: return "PIN_CODE_REPLY"; case BT_HCI_OP_ACCEPT_CONN_REQ:
case BT_HCI_OP_PIN_CODE_NEG_REPLY: return "PIN_CODE_NEG_REPLY"; return "ACCEPT_CONN_REQ";
case BT_HCI_OP_AUTH_REQUESTED: return "AUTH_REQUESTED"; case BT_HCI_OP_SETUP_SYNC_CONN:
case BT_HCI_OP_SET_CONN_ENCRYPT: return "SET_CONN_ENCRYPT"; return "SETUP_SYNC_CONN";
case BT_HCI_OP_REMOTE_NAME_REQUEST: return "REMOTE_NAME_REQUEST"; case BT_HCI_OP_ACCEPT_SYNC_CONN_REQ:
case BT_HCI_OP_REMOTE_NAME_CANCEL: return "REMOTE_NAME_CANCEL"; return "ACCEPT_SYNC_CONN_REQ";
case BT_HCI_OP_READ_REMOTE_FEATURES: return "READ_REMOTE_FEATURES"; case BT_HCI_OP_REJECT_CONN_REQ:
case BT_HCI_OP_READ_REMOTE_EXT_FEATURES: return "READ_REMOTE_EXT_FEATURES"; return "REJECT_CONN_REQ";
case BT_HCI_OP_READ_REMOTE_VERSION_INFO: return "READ_REMOTE_VERSION_INFO"; case BT_HCI_OP_LINK_KEY_REPLY:
case BT_HCI_OP_IO_CAPABILITY_REPLY: return "IO_CAPABILITY_REPLY"; return "LINK_KEY_REPLY";
case BT_HCI_OP_USER_CONFIRM_REPLY: return "USER_CONFIRM_REPLY"; case BT_HCI_OP_LINK_KEY_NEG_REPLY:
case BT_HCI_OP_USER_CONFIRM_NEG_REPLY: return "USER_CONFIRM_NEG_REPLY"; return "LINK_KEY_NEG_REPLY";
case BT_HCI_OP_USER_PASSKEY_REPLY: return "USER_PASSKEY_REPLY"; case BT_HCI_OP_PIN_CODE_REPLY:
case BT_HCI_OP_USER_PASSKEY_NEG_REPLY: return "USER_PASSKEY_NEG_REPLY"; return "PIN_CODE_REPLY";
case BT_HCI_OP_IO_CAPABILITY_NEG_REPLY: return "IO_CAPABILITY_NEG_REPLY"; case BT_HCI_OP_PIN_CODE_NEG_REPLY:
case BT_HCI_OP_SET_EVENT_MASK: return "SET_EVENT_MASK"; return "PIN_CODE_NEG_REPLY";
case BT_HCI_OP_RESET: return "RESET"; case BT_HCI_OP_AUTH_REQUESTED:
case BT_HCI_OP_WRITE_LOCAL_NAME: return "WRITE_LOCAL_NAME"; return "AUTH_REQUESTED";
case BT_HCI_OP_WRITE_PAGE_TIMEOUT: return "WRITE_PAGE_TIMEOUT"; case BT_HCI_OP_SET_CONN_ENCRYPT:
case BT_HCI_OP_WRITE_SCAN_ENABLE: return "WRITE_SCAN_ENABLE"; return "SET_CONN_ENCRYPT";
case BT_HCI_OP_READ_TX_POWER_LEVEL: return "READ_TX_POWER_LEVEL"; case BT_HCI_OP_REMOTE_NAME_REQUEST:
case BT_HCI_OP_SET_CTL_TO_HOST_FLOW: return "SET_CTL_TO_HOST_FLOW"; return "REMOTE_NAME_REQUEST";
case BT_HCI_OP_HOST_BUFFER_SIZE: return "HOST_BUFFER_SIZE"; case BT_HCI_OP_REMOTE_NAME_CANCEL:
case BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS: return "HOST_NUM_COMPLETED_PACKETS"; return "REMOTE_NAME_CANCEL";
case BT_HCI_OP_WRITE_INQUIRY_MODE: return "WRITE_INQUIRY_MODE"; case BT_HCI_OP_READ_REMOTE_FEATURES:
case BT_HCI_OP_WRITE_SSP_MODE: return "WRITE_SSP_MODE"; return "READ_REMOTE_FEATURES";
case BT_HCI_OP_SET_EVENT_MASK_PAGE_2: return "SET_EVENT_MASK_PAGE_2"; case BT_HCI_OP_READ_REMOTE_EXT_FEATURES:
case BT_HCI_OP_LE_WRITE_LE_HOST_SUPP: return "LE_WRITE_LE_HOST_SUPP"; return "READ_REMOTE_EXT_FEATURES";
case BT_HCI_OP_WRITE_SC_HOST_SUPP: return "WRITE_SC_HOST_SUPP"; case BT_HCI_OP_READ_REMOTE_VERSION_INFO:
case BT_HCI_OP_READ_AUTH_PAYLOAD_TIMEOUT: return "READ_AUTH_PAYLOAD_TIMEOUT"; return "READ_REMOTE_VERSION_INFO";
case BT_HCI_OP_WRITE_AUTH_PAYLOAD_TIMEOUT: return "WRITE_AUTH_PAYLOAD_TIMEOUT"; case BT_HCI_OP_IO_CAPABILITY_REPLY:
case BT_HCI_OP_READ_LOCAL_VERSION_INFO: return "READ_LOCAL_VERSION_INFO"; return "IO_CAPABILITY_REPLY";
case BT_HCI_OP_READ_SUPPORTED_COMMANDS: return "READ_SUPPORTED_COMMANDS"; case BT_HCI_OP_USER_CONFIRM_REPLY:
case BT_HCI_OP_READ_LOCAL_EXT_FEATURES: return "READ_LOCAL_EXT_FEATURES"; return "USER_CONFIRM_REPLY";
case BT_HCI_OP_READ_LOCAL_FEATURES: return "READ_LOCAL_FEATURES"; case BT_HCI_OP_USER_CONFIRM_NEG_REPLY:
case BT_HCI_OP_READ_BUFFER_SIZE: return "READ_BUFFER_SIZE"; return "USER_CONFIRM_NEG_REPLY";
case BT_HCI_OP_READ_BD_ADDR: return "READ_BD_ADDR"; case BT_HCI_OP_USER_PASSKEY_REPLY:
case BT_HCI_OP_READ_RSSI: return "READ_RSSI"; return "USER_PASSKEY_REPLY";
case BT_HCI_OP_READ_ENCRYPTION_KEY_SIZE: return "READ_ENCRYPTION_KEY_SIZE"; case BT_HCI_OP_USER_PASSKEY_NEG_REPLY:
case BT_HCI_OP_LE_SET_EVENT_MASK: return "LE_SET_EVENT_MASK"; return "USER_PASSKEY_NEG_REPLY";
case BT_HCI_OP_LE_READ_BUFFER_SIZE: return "LE_READ_BUFFER_SIZE"; case BT_HCI_OP_IO_CAPABILITY_NEG_REPLY:
case BT_HCI_OP_LE_READ_LOCAL_FEATURES: return "LE_READ_LOCAL_FEATURES"; return "IO_CAPABILITY_NEG_REPLY";
case BT_HCI_OP_LE_SET_RANDOM_ADDRESS: return "LE_SET_RANDOM_ADDRESS"; case BT_HCI_OP_SET_EVENT_MASK:
case BT_HCI_OP_LE_SET_ADV_PARAM: return "LE_SET_ADV_PARAM"; return "SET_EVENT_MASK";
case BT_HCI_OP_LE_READ_ADV_CHAN_TX_POWER: return "LE_READ_ADV_CHAN_TX_POWER"; case BT_HCI_OP_RESET:
case BT_HCI_OP_LE_SET_ADV_DATA: return "LE_SET_ADV_DATA"; return "RESET";
case BT_HCI_OP_LE_SET_SCAN_RSP_DATA: return "LE_SET_SCAN_RSP_DATA"; case BT_HCI_OP_WRITE_LOCAL_NAME:
case BT_HCI_OP_LE_SET_ADV_ENABLE: return "LE_SET_ADV_ENABLE"; return "WRITE_LOCAL_NAME";
case BT_HCI_OP_LE_SET_SCAN_PARAM: return "LE_SET_SCAN_PARAM"; case BT_HCI_OP_WRITE_PAGE_TIMEOUT:
case BT_HCI_OP_LE_SET_SCAN_ENABLE: return "LE_SET_SCAN_ENABLE"; return "WRITE_PAGE_TIMEOUT";
case BT_HCI_OP_LE_CREATE_CONN: return "LE_CREATE_CONN"; case BT_HCI_OP_WRITE_SCAN_ENABLE:
case BT_HCI_OP_LE_CREATE_CONN_CANCEL: return "LE_CREATE_CONN_CANCEL"; return "WRITE_SCAN_ENABLE";
case BT_HCI_OP_LE_READ_WL_SIZE: return "LE_READ_WL_SIZE"; case BT_HCI_OP_READ_TX_POWER_LEVEL:
case BT_HCI_OP_LE_CLEAR_WL: return "LE_CLEAR_WL"; return "READ_TX_POWER_LEVEL";
case BT_HCI_OP_LE_ADD_DEV_TO_WL: return "LE_ADD_DEV_TO_WL"; case BT_HCI_OP_SET_CTL_TO_HOST_FLOW:
case BT_HCI_OP_LE_REM_DEV_FROM_WL: return "LE_REM_DEV_FROM_WL"; return "SET_CTL_TO_HOST_FLOW";
case BT_HCI_OP_LE_CONN_UPDATE: return "LE_CONN_UPDATE"; case BT_HCI_OP_HOST_BUFFER_SIZE:
case BT_HCI_OP_LE_SET_HOST_CHAN_CLASSIF: return "LE_SET_HOST_CHAN_CLASSIF"; return "HOST_BUFFER_SIZE";
case BT_HCI_OP_LE_READ_CHAN_MAP: return "LE_READ_CHAN_MAP"; case BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS:
case BT_HCI_OP_LE_READ_REMOTE_FEATURES: return "LE_READ_REMOTE_FEATURES"; return "HOST_NUM_COMPLETED_PACKETS";
case BT_HCI_OP_LE_ENCRYPT: return "LE_ENCRYPT"; case BT_HCI_OP_WRITE_INQUIRY_MODE:
case BT_HCI_OP_LE_RAND: return "LE_RAND"; return "WRITE_INQUIRY_MODE";
case BT_HCI_OP_LE_START_ENCRYPTION: return "LE_START_ENCRYPTION"; case BT_HCI_OP_WRITE_SSP_MODE:
case BT_HCI_OP_LE_LTK_REQ_REPLY: return "LE_LTK_REQ_REPLY"; return "WRITE_SSP_MODE";
case BT_HCI_OP_LE_LTK_REQ_NEG_REPLY: return "LE_LTK_REQ_NEG_REPLY"; case BT_HCI_OP_SET_EVENT_MASK_PAGE_2:
case BT_HCI_OP_LE_READ_SUPP_STATES: return "LE_READ_SUPP_STATES"; return "SET_EVENT_MASK_PAGE_2";
case BT_HCI_OP_LE_RX_TEST: return "LE_RX_TEST"; case BT_HCI_OP_LE_WRITE_LE_HOST_SUPP:
case BT_HCI_OP_LE_TX_TEST: return "LE_TX_TEST"; return "LE_WRITE_LE_HOST_SUPP";
case BT_HCI_OP_LE_TEST_END: return "LE_TEST_END"; case BT_HCI_OP_WRITE_SC_HOST_SUPP:
case BT_HCI_OP_LE_CONN_PARAM_REQ_REPLY: return "LE_CONN_PARAM_REQ_REPLY"; return "WRITE_SC_HOST_SUPP";
case BT_HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY: return "LE_CONN_PARAM_REQ_NEG_REPLY"; case BT_HCI_OP_READ_AUTH_PAYLOAD_TIMEOUT:
case BT_HCI_OP_LE_SET_DATA_LEN: return "LE_SET_DATA_LEN"; return "READ_AUTH_PAYLOAD_TIMEOUT";
case BT_HCI_OP_LE_READ_DEFAULT_DATA_LEN: return "LE_READ_DEFAULT_DATA_LEN"; case BT_HCI_OP_WRITE_AUTH_PAYLOAD_TIMEOUT:
case BT_HCI_OP_LE_WRITE_DEFAULT_DATA_LEN: return "LE_WRITE_DEFAULT_DATA_LEN"; return "WRITE_AUTH_PAYLOAD_TIMEOUT";
case BT_HCI_OP_LE_P256_PUBLIC_KEY: return "LE_P256_PUBLIC_KEY"; case BT_HCI_OP_READ_LOCAL_VERSION_INFO:
case BT_HCI_OP_LE_GENERATE_DHKEY: return "LE_GENERATE_DHKEY"; return "READ_LOCAL_VERSION_INFO";
case BT_HCI_OP_LE_ADD_DEV_TO_RL: return "LE_ADD_DEV_TO_RL"; case BT_HCI_OP_READ_SUPPORTED_COMMANDS:
case BT_HCI_OP_LE_REM_DEV_FROM_RL: return "LE_REM_DEV_FROM_RL"; return "READ_SUPPORTED_COMMANDS";
case BT_HCI_OP_LE_CLEAR_RL: return "LE_CLEAR_RL"; case BT_HCI_OP_READ_LOCAL_EXT_FEATURES:
case BT_HCI_OP_LE_READ_RL_SIZE: return "LE_READ_RL_SIZE"; return "READ_LOCAL_EXT_FEATURES";
case BT_HCI_OP_LE_READ_PEER_RPA: return "LE_READ_PEER_RPA"; case BT_HCI_OP_READ_LOCAL_FEATURES:
case BT_HCI_OP_LE_READ_LOCAL_RPA: return "LE_READ_LOCAL_RPA"; return "READ_LOCAL_FEATURES";
case BT_HCI_OP_LE_SET_ADDR_RES_ENABLE: return "LE_SET_ADDR_RES_ENABLE"; case BT_HCI_OP_READ_BUFFER_SIZE:
case BT_HCI_OP_LE_SET_RPA_TIMEOUT: return "LE_SET_RPA_TIMEOUT"; return "READ_BUFFER_SIZE";
case BT_HCI_OP_LE_READ_MAX_DATA_LEN: return "LE_READ_MAX_DATA_LEN"; case BT_HCI_OP_READ_BD_ADDR:
case BT_HCI_OP_LE_READ_PHY: return "LE_READ_PHY"; return "READ_BD_ADDR";
case BT_HCI_OP_LE_SET_DEFAULT_PHY: return "LE_SET_DEFAULT_PHY"; case BT_HCI_OP_READ_RSSI:
case BT_HCI_OP_LE_SET_PHY: return "LE_SET_PHY"; return "READ_RSSI";
case BT_HCI_OP_LE_ENH_RX_TEST: return "LE_ENH_RX_TEST"; case BT_HCI_OP_READ_ENCRYPTION_KEY_SIZE:
case BT_HCI_OP_LE_ENH_TX_TEST: return "LE_ENH_TX_TEST"; return "READ_ENCRYPTION_KEY_SIZE";
case BT_HCI_OP_LE_SET_ADV_SET_RANDOM_ADDR: return "LE_SET_ADV_SET_RANDOM_ADDR"; case BT_HCI_OP_LE_SET_EVENT_MASK:
case BT_HCI_OP_LE_SET_EXT_ADV_PARAM: return "LE_SET_EXT_ADV_PARAM"; return "LE_SET_EVENT_MASK";
case BT_HCI_OP_LE_SET_EXT_ADV_DATA: return "LE_SET_EXT_ADV_DATA"; case BT_HCI_OP_LE_READ_BUFFER_SIZE:
case BT_HCI_OP_LE_SET_EXT_SCAN_RSP_DATA: return "LE_SET_EXT_SCAN_RSP_DATA"; return "LE_READ_BUFFER_SIZE";
case BT_HCI_OP_LE_SET_EXT_ADV_ENABLE: return "LE_SET_EXT_ADV_ENABLE"; case BT_HCI_OP_LE_READ_LOCAL_FEATURES:
case BT_HCI_OP_LE_READ_MAX_ADV_DATA_LEN: return "LE_READ_MAX_ADV_DATA_LEN"; return "LE_READ_LOCAL_FEATURES";
case BT_HCI_OP_LE_READ_NUM_ADV_SETS: return "LE_READ_NUM_ADV_SETS"; case BT_HCI_OP_LE_SET_RANDOM_ADDRESS:
case BT_HCI_OP_LE_REMOVE_ADV_SET: return "LE_REMOVE_ADV_SET"; return "LE_SET_RANDOM_ADDRESS";
case BT_HCI_OP_CLEAR_ADV_SETS: return "CLEAR_ADV_SETS"; case BT_HCI_OP_LE_SET_ADV_PARAM:
case BT_HCI_OP_LE_SET_PER_ADV_PARAM: return "LE_SET_PER_ADV_PARAM"; return "LE_SET_ADV_PARAM";
case BT_HCI_OP_LE_SET_PER_ADV_DATA: return "LE_SET_PER_ADV_DATA"; case BT_HCI_OP_LE_READ_ADV_CHAN_TX_POWER:
case BT_HCI_OP_LE_SET_PER_ADV_ENABLE: return "LE_SET_PER_ADV_ENABLE"; return "LE_READ_ADV_CHAN_TX_POWER";
case BT_HCI_OP_LE_SET_EXT_SCAN_PARAM: return "LE_SET_EXT_SCAN_PARAM"; case BT_HCI_OP_LE_SET_ADV_DATA:
case BT_HCI_OP_LE_SET_EXT_SCAN_ENABLE: return "LE_SET_EXT_SCAN_ENABLE"; return "LE_SET_ADV_DATA";
case BT_HCI_OP_LE_EXT_CREATE_CONN: return "LE_EXT_CREATE_CONN"; case BT_HCI_OP_LE_SET_SCAN_RSP_DATA:
case BT_HCI_OP_LE_PER_ADV_CREATE_SYNC: return "LE_PER_ADV_CREATE_SYNC"; return "LE_SET_SCAN_RSP_DATA";
case BT_HCI_OP_LE_PER_ADV_CREATE_SYNC_CANCEL: return "LE_PER_ADV_CREATE_SYNC_CANCEL"; case BT_HCI_OP_LE_SET_ADV_ENABLE:
case BT_HCI_OP_LE_PER_ADV_TERMINATE_SYNC: return "LE_PER_ADV_TERMINATE_SYNC"; return "LE_SET_ADV_ENABLE";
case BT_HCI_OP_LE_ADD_DEV_TO_PER_ADV_LIST: return "LE_ADD_DEV_TO_PER_ADV_LIST"; case BT_HCI_OP_LE_SET_SCAN_PARAM:
case BT_HCI_OP_LE_REM_DEV_FROM_PER_ADV_LIST: return "LE_REM_DEV_FROM_PER_ADV_LIST"; return "LE_SET_SCAN_PARAM";
case BT_HCI_OP_LE_CLEAR_PER_ADV_LIST: return "LE_CLEAR_PER_ADV_LIST"; case BT_HCI_OP_LE_SET_SCAN_ENABLE:
case BT_HCI_OP_LE_READ_PER_ADV_LIST_SIZE: return "LE_READ_PER_ADV_LIST_SIZE"; return "LE_SET_SCAN_ENABLE";
case BT_HCI_OP_LE_READ_TX_POWER: return "LE_READ_TX_POWER"; case BT_HCI_OP_LE_CREATE_CONN:
case BT_HCI_OP_LE_READ_RF_PATH_COMP: return "LE_READ_RF_PATH_COMP"; return "LE_CREATE_CONN";
case BT_HCI_OP_LE_WRITE_RF_PATH_COMP: return "LE_WRITE_RF_PATH_COMP"; case BT_HCI_OP_LE_CREATE_CONN_CANCEL:
case BT_HCI_OP_LE_SET_PRIVACY_MODE: return "LE_SET_PRIVACY_MODE"; return "LE_CREATE_CONN_CANCEL";
default: return ""; case BT_HCI_OP_LE_READ_WL_SIZE:
return "LE_READ_WL_SIZE";
case BT_HCI_OP_LE_CLEAR_WL:
return "LE_CLEAR_WL";
case BT_HCI_OP_LE_ADD_DEV_TO_WL:
return "LE_ADD_DEV_TO_WL";
case BT_HCI_OP_LE_REM_DEV_FROM_WL:
return "LE_REM_DEV_FROM_WL";
case BT_HCI_OP_LE_CONN_UPDATE:
return "LE_CONN_UPDATE";
case BT_HCI_OP_LE_SET_HOST_CHAN_CLASSIF:
return "LE_SET_HOST_CHAN_CLASSIF";
case BT_HCI_OP_LE_READ_CHAN_MAP:
return "LE_READ_CHAN_MAP";
case BT_HCI_OP_LE_READ_REMOTE_FEATURES:
return "LE_READ_REMOTE_FEATURES";
case BT_HCI_OP_LE_ENCRYPT:
return "LE_ENCRYPT";
case BT_HCI_OP_LE_RAND:
return "LE_RAND";
case BT_HCI_OP_LE_START_ENCRYPTION:
return "LE_START_ENCRYPTION";
case BT_HCI_OP_LE_LTK_REQ_REPLY:
return "LE_LTK_REQ_REPLY";
case BT_HCI_OP_LE_LTK_REQ_NEG_REPLY:
return "LE_LTK_REQ_NEG_REPLY";
case BT_HCI_OP_LE_READ_SUPP_STATES:
return "LE_READ_SUPP_STATES";
case BT_HCI_OP_LE_RX_TEST:
return "LE_RX_TEST";
case BT_HCI_OP_LE_TX_TEST:
return "LE_TX_TEST";
case BT_HCI_OP_LE_TEST_END:
return "LE_TEST_END";
case BT_HCI_OP_LE_CONN_PARAM_REQ_REPLY:
return "LE_CONN_PARAM_REQ_REPLY";
case BT_HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY:
return "LE_CONN_PARAM_REQ_NEG_REPLY";
case BT_HCI_OP_LE_SET_DATA_LEN:
return "LE_SET_DATA_LEN";
case BT_HCI_OP_LE_READ_DEFAULT_DATA_LEN:
return "LE_READ_DEFAULT_DATA_LEN";
case BT_HCI_OP_LE_WRITE_DEFAULT_DATA_LEN:
return "LE_WRITE_DEFAULT_DATA_LEN";
case BT_HCI_OP_LE_P256_PUBLIC_KEY:
return "LE_P256_PUBLIC_KEY";
case BT_HCI_OP_LE_GENERATE_DHKEY:
return "LE_GENERATE_DHKEY";
case BT_HCI_OP_LE_ADD_DEV_TO_RL:
return "LE_ADD_DEV_TO_RL";
case BT_HCI_OP_LE_REM_DEV_FROM_RL:
return "LE_REM_DEV_FROM_RL";
case BT_HCI_OP_LE_CLEAR_RL:
return "LE_CLEAR_RL";
case BT_HCI_OP_LE_READ_RL_SIZE:
return "LE_READ_RL_SIZE";
case BT_HCI_OP_LE_READ_PEER_RPA:
return "LE_READ_PEER_RPA";
case BT_HCI_OP_LE_READ_LOCAL_RPA:
return "LE_READ_LOCAL_RPA";
case BT_HCI_OP_LE_SET_ADDR_RES_ENABLE:
return "LE_SET_ADDR_RES_ENABLE";
case BT_HCI_OP_LE_SET_RPA_TIMEOUT:
return "LE_SET_RPA_TIMEOUT";
case BT_HCI_OP_LE_READ_MAX_DATA_LEN:
return "LE_READ_MAX_DATA_LEN";
case BT_HCI_OP_LE_READ_PHY:
return "LE_READ_PHY";
case BT_HCI_OP_LE_SET_DEFAULT_PHY:
return "LE_SET_DEFAULT_PHY";
case BT_HCI_OP_LE_SET_PHY:
return "LE_SET_PHY";
case BT_HCI_OP_LE_ENH_RX_TEST:
return "LE_ENH_RX_TEST";
case BT_HCI_OP_LE_ENH_TX_TEST:
return "LE_ENH_TX_TEST";
case BT_HCI_OP_LE_SET_ADV_SET_RANDOM_ADDR:
return "LE_SET_ADV_SET_RANDOM_ADDR";
case BT_HCI_OP_LE_SET_EXT_ADV_PARAM:
return "LE_SET_EXT_ADV_PARAM";
case BT_HCI_OP_LE_SET_EXT_ADV_DATA:
return "LE_SET_EXT_ADV_DATA";
case BT_HCI_OP_LE_SET_EXT_SCAN_RSP_DATA:
return "LE_SET_EXT_SCAN_RSP_DATA";
case BT_HCI_OP_LE_SET_EXT_ADV_ENABLE:
return "LE_SET_EXT_ADV_ENABLE";
case BT_HCI_OP_LE_READ_MAX_ADV_DATA_LEN:
return "LE_READ_MAX_ADV_DATA_LEN";
case BT_HCI_OP_LE_READ_NUM_ADV_SETS:
return "LE_READ_NUM_ADV_SETS";
case BT_HCI_OP_LE_REMOVE_ADV_SET:
return "LE_REMOVE_ADV_SET";
case BT_HCI_OP_CLEAR_ADV_SETS:
return "CLEAR_ADV_SETS";
case BT_HCI_OP_LE_SET_PER_ADV_PARAM:
return "LE_SET_PER_ADV_PARAM";
case BT_HCI_OP_LE_SET_PER_ADV_DATA:
return "LE_SET_PER_ADV_DATA";
case BT_HCI_OP_LE_SET_PER_ADV_ENABLE:
return "LE_SET_PER_ADV_ENABLE";
case BT_HCI_OP_LE_SET_EXT_SCAN_PARAM:
return "LE_SET_EXT_SCAN_PARAM";
case BT_HCI_OP_LE_SET_EXT_SCAN_ENABLE:
return "LE_SET_EXT_SCAN_ENABLE";
case BT_HCI_OP_LE_EXT_CREATE_CONN:
return "LE_EXT_CREATE_CONN";
case BT_HCI_OP_LE_PER_ADV_CREATE_SYNC:
return "LE_PER_ADV_CREATE_SYNC";
case BT_HCI_OP_LE_PER_ADV_CREATE_SYNC_CANCEL:
return "LE_PER_ADV_CREATE_SYNC_CANCEL";
case BT_HCI_OP_LE_PER_ADV_TERMINATE_SYNC:
return "LE_PER_ADV_TERMINATE_SYNC";
case BT_HCI_OP_LE_ADD_DEV_TO_PER_ADV_LIST:
return "LE_ADD_DEV_TO_PER_ADV_LIST";
case BT_HCI_OP_LE_REM_DEV_FROM_PER_ADV_LIST:
return "LE_REM_DEV_FROM_PER_ADV_LIST";
case BT_HCI_OP_LE_CLEAR_PER_ADV_LIST:
return "LE_CLEAR_PER_ADV_LIST";
case BT_HCI_OP_LE_READ_PER_ADV_LIST_SIZE:
return "LE_READ_PER_ADV_LIST_SIZE";
case BT_HCI_OP_LE_READ_TX_POWER:
return "LE_READ_TX_POWER";
case BT_HCI_OP_LE_READ_RF_PATH_COMP:
return "LE_READ_RF_PATH_COMP";
case BT_HCI_OP_LE_WRITE_RF_PATH_COMP:
return "LE_WRITE_RF_PATH_COMP";
case BT_HCI_OP_LE_SET_PRIVACY_MODE:
return "LE_SET_PRIVACY_MODE";
default:
return "";
} }
} }
STATIC void dump_cmd_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) { STATIC void dump_cmd_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
h4_hci_cmd_pkt_t *pkt = (h4_hci_cmd_pkt_t *) pkt_data; h4_hci_cmd_pkt_t *pkt = (h4_hci_cmd_pkt_t *)pkt_data;
mp_printf(&mp_plat_print, mp_printf(&mp_plat_print,
"%s HCI COMMAND (%x) op: %s (%04x), len: %d, data: ", "%s HCI COMMAND (%x) op: %s (%04x), len: %d, data: ",
tx ? "TX->" : "RX<-", tx ? "TX->" : "RX<-",
pkt->pkt_type, pkt->pkt_type,
hci_opcode_name(pkt->opcode), pkt->opcode, pkt->param_len); hci_opcode_name(pkt->opcode), pkt->opcode, pkt->param_len);
for (size_t i = 0; i < pkt->param_len; i++) { for (size_t i = 0; i < pkt->param_len; i++) {
mp_printf(&mp_plat_print, "%02x ", pkt->params[i]); mp_printf(&mp_plat_print, "%02x ", pkt->params[i]);
} }
@ -278,12 +492,12 @@ STATIC void dump_cmd_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
} }
STATIC void dump_acl_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) { STATIC void dump_acl_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
h4_hci_acl_pkt_t *pkt = (h4_hci_acl_pkt_t *) pkt_data; h4_hci_acl_pkt_t *pkt = (h4_hci_acl_pkt_t *)pkt_data;
acl_data_t *acl = (acl_data_t *) pkt->data; acl_data_t *acl = (acl_data_t *)pkt->data;
mp_printf(&mp_plat_print, mp_printf(&mp_plat_print,
"%s HCI ACLDATA (%x) ", "%s HCI ACLDATA (%x) ",
tx ? "TX->" : "RX<-", pkt->pkt_type); tx ? "TX->" : "RX<-", pkt->pkt_type);
if (pkt->pb != ACL_DATA_PB_MIDDLE && acl->cid == BT_L2CAP_CID_ATT) { if (pkt->pb != ACL_DATA_PB_MIDDLE && acl->cid == BT_L2CAP_CID_ATT) {
// This is the start of a fragmented acl_data packet or is a full packet, // This is the start of a fragmented acl_data packet or is a full packet,
@ -292,14 +506,14 @@ STATIC void dump_acl_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
} }
mp_printf(&mp_plat_print, mp_printf(&mp_plat_print,
"handle: %04x, pb: %d, bc: %d, data_len: %d, ", "handle: %04x, pb: %d, bc: %d, data_len: %d, ",
pkt->handle, pkt->pb, pkt->bc, pkt->data_len); pkt->handle, pkt->pb, pkt->bc, pkt->data_len);
if (pkt->pb != ACL_DATA_PB_MIDDLE) { if (pkt->pb != ACL_DATA_PB_MIDDLE) {
// This is the start of a fragmented acl_data packet or is a full packet. // This is the start of a fragmented acl_data packet or is a full packet.
mp_printf(&mp_plat_print, mp_printf(&mp_plat_print,
"acl data_len: %d, cid: %04x, data: ", "acl data_len: %d, cid: %04x, data: ",
acl->acl_data_len, acl->cid); acl->acl_data_len, acl->cid);
for (size_t i = 0; i < acl->acl_data_len; i++) { for (size_t i = 0; i < acl->acl_data_len; i++) {
mp_printf(&mp_plat_print, "%02x ", acl->acl_data[i]); mp_printf(&mp_plat_print, "%02x ", acl->acl_data[i]);
} }
@ -316,15 +530,15 @@ STATIC void dump_acl_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
} }
STATIC void dump_evt_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) { STATIC void dump_evt_pkt(bool tx, uint8_t pkt_len, uint8_t pkt_data[]) {
h4_hci_evt_pkt_t *pkt = (h4_hci_evt_pkt_t *) pkt_data; h4_hci_evt_pkt_t *pkt = (h4_hci_evt_pkt_t *)pkt_data;
mp_printf(&mp_plat_print, mp_printf(&mp_plat_print,
"%s HCI EVENT (%x) evt: %s (%02x), param_len: %d, data: ", "%s HCI EVENT (%x) evt: %s (%02x), param_len: %d, data: ",
tx ? "TX->" : "RX<-", tx ? "TX->" : "RX<-",
pkt->pkt_type, pkt->pkt_type,
pkt->evt == BT_HCI_EVT_LE_META_EVENT pkt->evt == BT_HCI_EVT_LE_META_EVENT
? hci_evt_le_name(pkt->params[0]) ? hci_evt_le_name(pkt->params[0])
: hci_evt_name(pkt->evt), : hci_evt_name(pkt->evt),
pkt->evt, pkt->param_len); pkt->evt, pkt->param_len);
for (size_t i = 0; i < pkt->param_len; i++) { for (size_t i = 0; i < pkt->param_len; i++) {
mp_printf(&mp_plat_print, "%02x ", pkt->params[i]); mp_printf(&mp_plat_print, "%02x ", pkt->params[i]);
} }

View file

@ -29,40 +29,36 @@
/** Bluetooth Device Address */ /** Bluetooth Device Address */
typedef struct { typedef struct {
uint8_t val[6]; uint8_t val[6];
} bt_addr_t; } bt_addr_t;
/** Bluetooth LE Device Address */ /** Bluetooth LE Device Address */
typedef struct { typedef struct {
uint8_t type; uint8_t type;
bt_addr_t a; bt_addr_t a;
} bt_addr_le_t; } bt_addr_le_t;
#define BT_ADDR_ANY ((bt_addr_t[]) { { { 0, 0, 0, 0, 0, 0 } } }) #define BT_ADDR_ANY ((bt_addr_t[]) { { { 0, 0, 0, 0, 0, 0 } } })
#define BT_ADDR_NONE ((bt_addr_t[]) { { \ #define BT_ADDR_NONE ((bt_addr_t[]) { { \
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } }) { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } })
#define BT_ADDR_LE_ANY ((bt_addr_le_t[]) { { 0, { { 0, 0, 0, 0, 0, 0 } } } }) #define BT_ADDR_LE_ANY ((bt_addr_le_t[]) { { 0, { { 0, 0, 0, 0, 0, 0 } } } })
#define BT_ADDR_LE_NONE ((bt_addr_le_t[]) { { 0, \ #define BT_ADDR_LE_NONE ((bt_addr_le_t[]) { { 0, \
{ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } } }) { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } } })
static inline int bt_addr_cmp(const bt_addr_t *a, const bt_addr_t *b) static inline int bt_addr_cmp(const bt_addr_t *a, const bt_addr_t *b) {
{ return memcmp(a, b, sizeof(*a));
return memcmp(a, b, sizeof(*a));
} }
static inline int bt_addr_le_cmp(const bt_addr_le_t *a, const bt_addr_le_t *b) static inline int bt_addr_le_cmp(const bt_addr_le_t *a, const bt_addr_le_t *b) {
{ return memcmp(a, b, sizeof(*a));
return memcmp(a, b, sizeof(*a));
} }
static inline void bt_addr_copy(bt_addr_t *dst, const bt_addr_t *src) static inline void bt_addr_copy(bt_addr_t *dst, const bt_addr_t *src) {
{ memcpy(dst, src, sizeof(*dst));
memcpy(dst, src, sizeof(*dst));
} }
static inline void bt_addr_le_copy(bt_addr_le_t *dst, const bt_addr_le_t *src) static inline void bt_addr_le_copy(bt_addr_le_t *dst, const bt_addr_le_t *src) {
{ memcpy(dst, src, sizeof(*dst));
memcpy(dst, src, sizeof(*dst));
} }
#define BT_ADDR_IS_RPA(a) (((a)->val[5] & 0xc0) == 0x40) #define BT_ADDR_IS_RPA(a) (((a)->val[5] & 0xc0) == 0x40)
@ -76,22 +72,20 @@ static inline void bt_addr_le_copy(bt_addr_le_t *dst, const bt_addr_le_t *src)
int bt_addr_le_create_nrpa(bt_addr_le_t *addr); int bt_addr_le_create_nrpa(bt_addr_le_t *addr);
int bt_addr_le_create_static(bt_addr_le_t *addr); int bt_addr_le_create_static(bt_addr_le_t *addr);
static inline bool bt_addr_le_is_rpa(const bt_addr_le_t *addr) static inline bool bt_addr_le_is_rpa(const bt_addr_le_t *addr) {
{ if (addr->type != BT_ADDR_LE_RANDOM) {
if (addr->type != BT_ADDR_LE_RANDOM) { return false;
return false; }
}
return BT_ADDR_IS_RPA(&addr->a); return BT_ADDR_IS_RPA(&addr->a);
} }
static inline bool bt_addr_le_is_identity(const bt_addr_le_t *addr) static inline bool bt_addr_le_is_identity(const bt_addr_le_t *addr) {
{ if (addr->type == BT_ADDR_LE_PUBLIC) {
if (addr->type == BT_ADDR_LE_PUBLIC) { return true;
return true; }
}
return BT_ADDR_IS_STATIC(&addr->a); return BT_ADDR_IS_STATIC(&addr->a);
} }
/** /**

View file

@ -12,30 +12,30 @@
#define ZEPHYR_INCLUDE_BLUETOOTH_ATT_H_ #define ZEPHYR_INCLUDE_BLUETOOTH_ATT_H_
/* Error codes for Error response PDU */ /* Error codes for Error response PDU */
#define BT_ATT_ERR_INVALID_HANDLE 0x01 #define BT_ATT_ERR_INVALID_HANDLE 0x01
#define BT_ATT_ERR_READ_NOT_PERMITTED 0x02 #define BT_ATT_ERR_READ_NOT_PERMITTED 0x02
#define BT_ATT_ERR_WRITE_NOT_PERMITTED 0x03 #define BT_ATT_ERR_WRITE_NOT_PERMITTED 0x03
#define BT_ATT_ERR_INVALID_PDU 0x04 #define BT_ATT_ERR_INVALID_PDU 0x04
#define BT_ATT_ERR_AUTHENTICATION 0x05 #define BT_ATT_ERR_AUTHENTICATION 0x05
#define BT_ATT_ERR_NOT_SUPPORTED 0x06 #define BT_ATT_ERR_NOT_SUPPORTED 0x06
#define BT_ATT_ERR_INVALID_OFFSET 0x07 #define BT_ATT_ERR_INVALID_OFFSET 0x07
#define BT_ATT_ERR_AUTHORIZATION 0x08 #define BT_ATT_ERR_AUTHORIZATION 0x08
#define BT_ATT_ERR_PREPARE_QUEUE_FULL 0x09 #define BT_ATT_ERR_PREPARE_QUEUE_FULL 0x09
#define BT_ATT_ERR_ATTRIBUTE_NOT_FOUND 0x0a #define BT_ATT_ERR_ATTRIBUTE_NOT_FOUND 0x0a
#define BT_ATT_ERR_ATTRIBUTE_NOT_LONG 0x0b #define BT_ATT_ERR_ATTRIBUTE_NOT_LONG 0x0b
#define BT_ATT_ERR_ENCRYPTION_KEY_SIZE 0x0c #define BT_ATT_ERR_ENCRYPTION_KEY_SIZE 0x0c
#define BT_ATT_ERR_INVALID_ATTRIBUTE_LEN 0x0d #define BT_ATT_ERR_INVALID_ATTRIBUTE_LEN 0x0d
#define BT_ATT_ERR_UNLIKELY 0x0e #define BT_ATT_ERR_UNLIKELY 0x0e
#define BT_ATT_ERR_INSUFFICIENT_ENCRYPTION 0x0f #define BT_ATT_ERR_INSUFFICIENT_ENCRYPTION 0x0f
#define BT_ATT_ERR_UNSUPPORTED_GROUP_TYPE 0x10 #define BT_ATT_ERR_UNSUPPORTED_GROUP_TYPE 0x10
#define BT_ATT_ERR_INSUFFICIENT_RESOURCES 0x11 #define BT_ATT_ERR_INSUFFICIENT_RESOURCES 0x11
#define BT_ATT_ERR_DB_OUT_OF_SYNC 0x12 #define BT_ATT_ERR_DB_OUT_OF_SYNC 0x12
#define BT_ATT_ERR_VALUE_NOT_ALLOWED 0x13 #define BT_ATT_ERR_VALUE_NOT_ALLOWED 0x13
/* Common Profile Error Codes (from CSS) */ /* Common Profile Error Codes (from CSS) */
#define BT_ATT_ERR_WRITE_REQ_REJECTED 0xfc #define BT_ATT_ERR_WRITE_REQ_REJECTED 0xfc
#define BT_ATT_ERR_CCC_IMPROPER_CONF 0xfd #define BT_ATT_ERR_CCC_IMPROPER_CONF 0xfd
#define BT_ATT_ERR_PROCEDURE_IN_PROGRESS 0xfe #define BT_ATT_ERR_PROCEDURE_IN_PROGRESS 0xfe
#define BT_ATT_ERR_OUT_OF_RANGE 0xff #define BT_ATT_ERR_OUT_OF_RANGE 0xff
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_ATT_H_ */ #endif /* ZEPHYR_INCLUDE_BLUETOOTH_ATT_H_ */

View file

@ -13,260 +13,260 @@
// for __packed // for __packed
#include <sys/cdefs.h> #include <sys/cdefs.h>
#define BT_EATT_PSM 0x27 #define BT_EATT_PSM 0x27
#define BT_ATT_DEFAULT_LE_MTU 23 #define BT_ATT_DEFAULT_LE_MTU 23
#define BT_ATT_TIMEOUT K_SECONDS(30) #define BT_ATT_TIMEOUT K_SECONDS(30)
//FIX #if BT_L2CAP_RX_MTU < CONFIG_BT_L2CAP_TX_MTU // FIX #if BT_L2CAP_RX_MTU < CONFIG_BT_L2CAP_TX_MTU
// #define BT_ATT_MTU BT_L2CAP_RX_MTU // #define BT_ATT_MTU BT_L2CAP_RX_MTU
// #else // #else
// #define BT_ATT_MTU CONFIG_BT_L2CAP_TX_MTU // #define BT_ATT_MTU CONFIG_BT_L2CAP_TX_MTU
// #endif // #endif
struct bt_att_hdr { struct bt_att_hdr {
uint8_t code; uint8_t code;
} __packed; } __packed;
#define BT_ATT_OP_ERROR_RSP 0x01 #define BT_ATT_OP_ERROR_RSP 0x01
struct bt_att_error_rsp { struct bt_att_error_rsp {
uint8_t request; uint8_t request;
uint16_t handle; uint16_t handle;
uint8_t error; uint8_t error;
} __packed; } __packed;
#define BT_ATT_OP_MTU_REQ 0x02 #define BT_ATT_OP_MTU_REQ 0x02
struct bt_att_exchange_mtu_req { struct bt_att_exchange_mtu_req {
uint16_t mtu; uint16_t mtu;
} __packed; } __packed;
#define BT_ATT_OP_MTU_RSP 0x03 #define BT_ATT_OP_MTU_RSP 0x03
struct bt_att_exchange_mtu_rsp { struct bt_att_exchange_mtu_rsp {
uint16_t mtu; uint16_t mtu;
} __packed; } __packed;
/* Find Information Request */ /* Find Information Request */
#define BT_ATT_OP_FIND_INFO_REQ 0x04 #define BT_ATT_OP_FIND_INFO_REQ 0x04
struct bt_att_find_info_req { struct bt_att_find_info_req {
uint16_t start_handle; uint16_t start_handle;
uint16_t end_handle; uint16_t end_handle;
} __packed; } __packed;
/* Format field values for BT_ATT_OP_FIND_INFO_RSP */ /* Format field values for BT_ATT_OP_FIND_INFO_RSP */
#define BT_ATT_INFO_16 0x01 #define BT_ATT_INFO_16 0x01
#define BT_ATT_INFO_128 0x02 #define BT_ATT_INFO_128 0x02
struct bt_att_info_16 { struct bt_att_info_16 {
uint16_t handle; uint16_t handle;
uint16_t uuid; uint16_t uuid;
} __packed; } __packed;
struct bt_att_info_128 { struct bt_att_info_128 {
uint16_t handle; uint16_t handle;
uint8_t uuid[16]; uint8_t uuid[16];
} __packed; } __packed;
/* Find Information Response */ /* Find Information Response */
#define BT_ATT_OP_FIND_INFO_RSP 0x05 #define BT_ATT_OP_FIND_INFO_RSP 0x05
struct bt_att_find_info_rsp { struct bt_att_find_info_rsp {
uint8_t format; uint8_t format;
uint8_t info[]; uint8_t info[];
} __packed; } __packed;
/* Find By Type Value Request */ /* Find By Type Value Request */
#define BT_ATT_OP_FIND_TYPE_REQ 0x06 #define BT_ATT_OP_FIND_TYPE_REQ 0x06
struct bt_att_find_type_req { struct bt_att_find_type_req {
uint16_t start_handle; uint16_t start_handle;
uint16_t end_handle; uint16_t end_handle;
uint16_t type; uint16_t type;
uint8_t value[]; uint8_t value[];
} __packed; } __packed;
struct bt_att_handle_group { struct bt_att_handle_group {
uint16_t start_handle; uint16_t start_handle;
uint16_t end_handle; uint16_t end_handle;
} __packed; } __packed;
/* Find By Type Value Response */ /* Find By Type Value Response */
#define BT_ATT_OP_FIND_TYPE_RSP 0x07 #define BT_ATT_OP_FIND_TYPE_RSP 0x07
struct bt_att_find_type_rsp { struct bt_att_find_type_rsp {
uint8_t _dummy[0]; uint8_t _dummy[0];
struct bt_att_handle_group list[]; struct bt_att_handle_group list[];
} __packed; } __packed;
/* Read By Type Request */ /* Read By Type Request */
#define BT_ATT_OP_READ_TYPE_REQ 0x08 #define BT_ATT_OP_READ_TYPE_REQ 0x08
struct bt_att_read_type_req { struct bt_att_read_type_req {
uint16_t start_handle; uint16_t start_handle;
uint16_t end_handle; uint16_t end_handle;
uint8_t uuid[]; uint8_t uuid[];
} __packed; } __packed;
struct bt_att_data { struct bt_att_data {
uint16_t handle; uint16_t handle;
uint8_t value[]; uint8_t value[];
} __packed; } __packed;
/* Read By Type Response */ /* Read By Type Response */
#define BT_ATT_OP_READ_TYPE_RSP 0x09 #define BT_ATT_OP_READ_TYPE_RSP 0x09
struct bt_att_read_type_rsp { struct bt_att_read_type_rsp {
uint8_t len; uint8_t len;
struct bt_att_data data[]; struct bt_att_data data[];
} __packed; } __packed;
/* Read Request */ /* Read Request */
#define BT_ATT_OP_READ_REQ 0x0a #define BT_ATT_OP_READ_REQ 0x0a
struct bt_att_read_req { struct bt_att_read_req {
uint16_t handle; uint16_t handle;
} __packed; } __packed;
/* Read Response */ /* Read Response */
#define BT_ATT_OP_READ_RSP 0x0b #define BT_ATT_OP_READ_RSP 0x0b
struct bt_att_read_rsp { struct bt_att_read_rsp {
uint8_t _dummy[0]; uint8_t _dummy[0];
uint8_t value[]; uint8_t value[];
} __packed; } __packed;
/* Read Blob Request */ /* Read Blob Request */
#define BT_ATT_OP_READ_BLOB_REQ 0x0c #define BT_ATT_OP_READ_BLOB_REQ 0x0c
struct bt_att_read_blob_req { struct bt_att_read_blob_req {
uint16_t handle; uint16_t handle;
uint16_t offset; uint16_t offset;
} __packed; } __packed;
/* Read Blob Response */ /* Read Blob Response */
#define BT_ATT_OP_READ_BLOB_RSP 0x0d #define BT_ATT_OP_READ_BLOB_RSP 0x0d
struct bt_att_read_blob_rsp { struct bt_att_read_blob_rsp {
uint8_t _dummy[0]; uint8_t _dummy[0];
uint8_t value[]; uint8_t value[];
} __packed; } __packed;
/* Read Multiple Request */ /* Read Multiple Request */
#define BT_ATT_READ_MULT_MIN_LEN_REQ 0x04 #define BT_ATT_READ_MULT_MIN_LEN_REQ 0x04
#define BT_ATT_OP_READ_MULT_REQ 0x0e #define BT_ATT_OP_READ_MULT_REQ 0x0e
struct bt_att_read_mult_req { struct bt_att_read_mult_req {
uint8_t _dummy[0]; uint8_t _dummy[0];
uint16_t handles[]; uint16_t handles[];
} __packed; } __packed;
/* Read Multiple Respose */ /* Read Multiple Respose */
#define BT_ATT_OP_READ_MULT_RSP 0x0f #define BT_ATT_OP_READ_MULT_RSP 0x0f
struct bt_att_read_mult_rsp { struct bt_att_read_mult_rsp {
uint8_t _dummy[0]; uint8_t _dummy[0];
uint8_t value[]; uint8_t value[];
} __packed; } __packed;
/* Read by Group Type Request */ /* Read by Group Type Request */
#define BT_ATT_OP_READ_GROUP_REQ 0x10 #define BT_ATT_OP_READ_GROUP_REQ 0x10
struct bt_att_read_group_req { struct bt_att_read_group_req {
uint16_t start_handle; uint16_t start_handle;
uint16_t end_handle; uint16_t end_handle;
uint8_t uuid[]; uint8_t uuid[];
} __packed; } __packed;
struct bt_att_group_data { struct bt_att_group_data {
uint16_t start_handle; uint16_t start_handle;
uint16_t end_handle; uint16_t end_handle;
uint8_t value[]; uint8_t value[];
} __packed; } __packed;
/* Read by Group Type Response */ /* Read by Group Type Response */
#define BT_ATT_OP_READ_GROUP_RSP 0x11 #define BT_ATT_OP_READ_GROUP_RSP 0x11
struct bt_att_read_group_rsp { struct bt_att_read_group_rsp {
uint8_t len; uint8_t len;
struct bt_att_group_data data[]; struct bt_att_group_data data[];
} __packed; } __packed;
/* Write Request */ /* Write Request */
#define BT_ATT_OP_WRITE_REQ 0x12 #define BT_ATT_OP_WRITE_REQ 0x12
struct bt_att_write_req { struct bt_att_write_req {
uint16_t handle; uint16_t handle;
uint8_t value[]; uint8_t value[];
} __packed; } __packed;
/* Write Response */ /* Write Response */
#define BT_ATT_OP_WRITE_RSP 0x13 #define BT_ATT_OP_WRITE_RSP 0x13
/* Prepare Write Request */ /* Prepare Write Request */
#define BT_ATT_OP_PREPARE_WRITE_REQ 0x16 #define BT_ATT_OP_PREPARE_WRITE_REQ 0x16
struct bt_att_prepare_write_req { struct bt_att_prepare_write_req {
uint16_t handle; uint16_t handle;
uint16_t offset; uint16_t offset;
uint8_t value[]; uint8_t value[];
} __packed; } __packed;
/* Prepare Write Respond */ /* Prepare Write Respond */
#define BT_ATT_OP_PREPARE_WRITE_RSP 0x17 #define BT_ATT_OP_PREPARE_WRITE_RSP 0x17
struct bt_att_prepare_write_rsp { struct bt_att_prepare_write_rsp {
uint16_t handle; uint16_t handle;
uint16_t offset; uint16_t offset;
uint8_t value[]; uint8_t value[];
} __packed; } __packed;
/* Execute Write Request */ /* Execute Write Request */
#define BT_ATT_FLAG_CANCEL 0x00 #define BT_ATT_FLAG_CANCEL 0x00
#define BT_ATT_FLAG_EXEC 0x01 #define BT_ATT_FLAG_EXEC 0x01
#define BT_ATT_OP_EXEC_WRITE_REQ 0x18 #define BT_ATT_OP_EXEC_WRITE_REQ 0x18
struct bt_att_exec_write_req { struct bt_att_exec_write_req {
uint8_t flags; uint8_t flags;
} __packed; } __packed;
/* Execute Write Response */ /* Execute Write Response */
#define BT_ATT_OP_EXEC_WRITE_RSP 0x19 #define BT_ATT_OP_EXEC_WRITE_RSP 0x19
/* Handle Value Notification */ /* Handle Value Notification */
#define BT_ATT_OP_NOTIFY 0x1b #define BT_ATT_OP_NOTIFY 0x1b
struct bt_att_notify { struct bt_att_notify {
uint16_t handle; uint16_t handle;
uint8_t value[]; uint8_t value[];
} __packed; } __packed;
/* Handle Value Indication */ /* Handle Value Indication */
#define BT_ATT_OP_INDICATE 0x1d #define BT_ATT_OP_INDICATE 0x1d
struct bt_att_indicate { struct bt_att_indicate {
uint16_t handle; uint16_t handle;
uint8_t value[]; uint8_t value[];
} __packed; } __packed;
/* Handle Value Confirm */ /* Handle Value Confirm */
#define BT_ATT_OP_CONFIRM 0x1e #define BT_ATT_OP_CONFIRM 0x1e
struct bt_att_signature { struct bt_att_signature {
uint8_t value[12]; uint8_t value[12];
} __packed; } __packed;
#define BT_ATT_OP_READ_MULT_VL_REQ 0x20 #define BT_ATT_OP_READ_MULT_VL_REQ 0x20
struct bt_att_read_mult_vl_req { struct bt_att_read_mult_vl_req {
uint8_t _dummy[0]; uint8_t _dummy[0];
uint16_t handles[]; uint16_t handles[];
} __packed; } __packed;
/* Read Multiple Respose */ /* Read Multiple Respose */
#define BT_ATT_OP_READ_MULT_VL_RSP 0x21 #define BT_ATT_OP_READ_MULT_VL_RSP 0x21
struct bt_att_read_mult_vl_rsp { struct bt_att_read_mult_vl_rsp {
uint16_t len; uint16_t len;
uint8_t value[]; uint8_t value[];
} __packed; } __packed;
/* Handle Multiple Value Notification */ /* Handle Multiple Value Notification */
#define BT_ATT_OP_NOTIFY_MULT 0x23 #define BT_ATT_OP_NOTIFY_MULT 0x23
struct bt_att_notify_mult { struct bt_att_notify_mult {
uint16_t handle; uint16_t handle;
uint16_t len; uint16_t len;
uint8_t value[]; uint8_t value[];
} __packed; } __packed;
/* Write Command */ /* Write Command */
#define BT_ATT_OP_WRITE_CMD 0x52 #define BT_ATT_OP_WRITE_CMD 0x52
struct bt_att_write_cmd { struct bt_att_write_cmd {
uint16_t handle; uint16_t handle;
uint8_t value[]; uint8_t value[];
} __packed; } __packed;
/* Signed Write Command */ /* Signed Write Command */
#define BT_ATT_OP_SIGNED_WRITE_CMD 0xd2 #define BT_ATT_OP_SIGNED_WRITE_CMD 0xd2
struct bt_att_signed_write_cmd { struct bt_att_signed_write_cmd {
uint16_t handle; uint16_t handle;
uint8_t value[]; uint8_t value[];
} __packed; } __packed;

File diff suppressed because it is too large Load diff

View file

@ -50,20 +50,20 @@ extern "C" {
int bt_send(struct net_buf *buf); int bt_send(struct net_buf *buf);
enum { enum {
/** Passthrough mode /** Passthrough mode
* *
* While in this mode the buffers are passed as is between the stack * While in this mode the buffers are passed as is between the stack
* and the driver. * and the driver.
*/ */
BT_HCI_RAW_MODE_PASSTHROUGH = 0x00, BT_HCI_RAW_MODE_PASSTHROUGH = 0x00,
/** H:4 mode /** H:4 mode
* *
* While in this mode H:4 headers will added into the buffers * While in this mode H:4 headers will added into the buffers
* according to the buffer type when coming from the stack and will be * according to the buffer type when coming from the stack and will be
* removed and used to set the buffer type. * removed and used to set the buffer type.
*/ */
BT_HCI_RAW_MODE_H4 = 0x01, BT_HCI_RAW_MODE_H4 = 0x01,
}; };
/** @brief Set Bluetooth RAW channel mode /** @brief Set Bluetooth RAW channel mode
@ -93,31 +93,31 @@ uint8_t bt_hci_raw_get_mode(void);
* @param _func Handler function to be called. * @param _func Handler function to be called.
*/ */
#define BT_HCI_RAW_CMD_EXT(_op, _min_len, _func) \ #define BT_HCI_RAW_CMD_EXT(_op, _min_len, _func) \
{ \ { \
.op = _op, \ .op = _op, \
.min_len = _min_len, \ .min_len = _min_len, \
.func = _func, \ .func = _func, \
} }
struct bt_hci_raw_cmd_ext { struct bt_hci_raw_cmd_ext {
/** Opcode of the command */ /** Opcode of the command */
uint16_t op; uint16_t op;
/** Minimal length of the command */ /** Minimal length of the command */
size_t min_len; size_t min_len;
/** Handler function. /** Handler function.
* *
* Handler function to be called when a command is intercepted. * Handler function to be called when a command is intercepted.
* *
* @param buf Buffer containing the command. * @param buf Buffer containing the command.
* *
* @return HCI Status code or BT_HCI_ERR_EXT_HANDLED if command has * @return HCI Status code or BT_HCI_ERR_EXT_HANDLED if command has
* been handled already and a response has been sent as oppose to * been handled already and a response has been sent as oppose to
* BT_HCI_ERR_SUCCESS which just indicates that the command can be * BT_HCI_ERR_SUCCESS which just indicates that the command can be
* sent to the controller to be processed. * sent to the controller to be processed.
*/ */
uint8_t (*func)(struct net_buf *buf); uint8_t (*func)(struct net_buf *buf);
}; };
/** @brief Register Bluetooth RAW command extension table /** @brief Register Bluetooth RAW command extension table

View file

@ -32,11 +32,11 @@ extern "C" {
#define BT_VS_CMD_BIT_READ_TX_POWER 14 #define BT_VS_CMD_BIT_READ_TX_POWER 14
#define BT_VS_CMD_SUP_FEAT(cmd) BT_LE_FEAT_TEST(cmd, \ #define BT_VS_CMD_SUP_FEAT(cmd) BT_LE_FEAT_TEST(cmd, \
BT_VS_CMD_BIT_SUP_FEAT) BT_VS_CMD_BIT_SUP_FEAT)
#define BT_VS_CMD_READ_STATIC_ADDRS(cmd) BT_LE_FEAT_TEST(cmd, \ #define BT_VS_CMD_READ_STATIC_ADDRS(cmd) BT_LE_FEAT_TEST(cmd, \
BT_VS_CMD_BIT_READ_STATIC_ADDRS) BT_VS_CMD_BIT_READ_STATIC_ADDRS)
#define BT_VS_CMD_READ_KEY_ROOTS(cmd) BT_LE_FEAT_TEST(cmd, \ #define BT_VS_CMD_READ_KEY_ROOTS(cmd) BT_LE_FEAT_TEST(cmd, \
BT_VS_CMD_BIT_READ_KEY_ROOTS) BT_VS_CMD_BIT_READ_KEY_ROOTS)
#define BT_HCI_VS_HW_PLAT_INTEL 0x0001 #define BT_HCI_VS_HW_PLAT_INTEL 0x0001
#define BT_HCI_VS_HW_PLAT_NORDIC 0x0002 #define BT_HCI_VS_HW_PLAT_NORDIC 0x0002
@ -50,44 +50,44 @@ extern "C" {
#define BT_HCI_VS_FW_VAR_VS_CTLR 0x0002 #define BT_HCI_VS_FW_VAR_VS_CTLR 0x0002
#define BT_HCI_VS_FW_VAR_FW_LOADER 0x0003 #define BT_HCI_VS_FW_VAR_FW_LOADER 0x0003
#define BT_HCI_VS_FW_VAR_RESCUE_IMG 0x0004 #define BT_HCI_VS_FW_VAR_RESCUE_IMG 0x0004
#define BT_HCI_OP_VS_READ_VERSION_INFO BT_OP(BT_OGF_VS, 0x0001) #define BT_HCI_OP_VS_READ_VERSION_INFO BT_OP(BT_OGF_VS, 0x0001)
struct bt_hci_rp_vs_read_version_info { struct bt_hci_rp_vs_read_version_info {
uint8_t status; uint8_t status;
uint16_t hw_platform; uint16_t hw_platform;
uint16_t hw_variant; uint16_t hw_variant;
uint8_t fw_variant; uint8_t fw_variant;
uint8_t fw_version; uint8_t fw_version;
uint16_t fw_revision; uint16_t fw_revision;
uint32_t fw_build; uint32_t fw_build;
} __packed; } __packed;
#define BT_HCI_OP_VS_READ_SUPPORTED_COMMANDS BT_OP(BT_OGF_VS, 0x0002) #define BT_HCI_OP_VS_READ_SUPPORTED_COMMANDS BT_OP(BT_OGF_VS, 0x0002)
struct bt_hci_rp_vs_read_supported_commands { struct bt_hci_rp_vs_read_supported_commands {
uint8_t status; uint8_t status;
uint8_t commands[64]; uint8_t commands[64];
} __packed; } __packed;
#define BT_HCI_OP_VS_READ_SUPPORTED_FEATURES BT_OP(BT_OGF_VS, 0x0003) #define BT_HCI_OP_VS_READ_SUPPORTED_FEATURES BT_OP(BT_OGF_VS, 0x0003)
struct bt_hci_rp_vs_read_supported_features { struct bt_hci_rp_vs_read_supported_features {
uint8_t status; uint8_t status;
uint8_t features[8]; uint8_t features[8];
} __packed; } __packed;
#define BT_HCI_OP_VS_SET_EVENT_MASK BT_OP(BT_OGF_VS, 0x0004) #define BT_HCI_OP_VS_SET_EVENT_MASK BT_OP(BT_OGF_VS, 0x0004)
struct bt_hci_cp_vs_set_event_mask { struct bt_hci_cp_vs_set_event_mask {
uint8_t event_mask[8]; uint8_t event_mask[8];
} __packed; } __packed;
#define BT_HCI_VS_RESET_SOFT 0x00 #define BT_HCI_VS_RESET_SOFT 0x00
#define BT_HCI_VS_RESET_HARD 0x01 #define BT_HCI_VS_RESET_HARD 0x01
#define BT_HCI_OP_VS_RESET BT_OP(BT_OGF_VS, 0x0005) #define BT_HCI_OP_VS_RESET BT_OP(BT_OGF_VS, 0x0005)
struct bt_hci_cp_vs_reset { struct bt_hci_cp_vs_reset {
uint8_t type; uint8_t type;
} __packed; } __packed;
#define BT_HCI_OP_VS_WRITE_BD_ADDR BT_OP(BT_OGF_VS, 0x0006) #define BT_HCI_OP_VS_WRITE_BD_ADDR BT_OP(BT_OGF_VS, 0x0006)
struct bt_hci_cp_vs_write_bd_addr { struct bt_hci_cp_vs_write_bd_addr {
bt_addr_t bdaddr; bt_addr_t bdaddr;
} __packed; } __packed;
#define BT_HCI_VS_TRACE_DISABLED 0x00 #define BT_HCI_VS_TRACE_DISABLED 0x00
@ -97,60 +97,60 @@ struct bt_hci_cp_vs_write_bd_addr {
#define BT_HCI_VS_TRACE_VDC 0x01 #define BT_HCI_VS_TRACE_VDC 0x01
#define BT_HCI_OP_VS_SET_TRACE_ENABLE BT_OP(BT_OGF_VS, 0x0007) #define BT_HCI_OP_VS_SET_TRACE_ENABLE BT_OP(BT_OGF_VS, 0x0007)
struct bt_hci_cp_vs_set_trace_enable { struct bt_hci_cp_vs_set_trace_enable {
uint8_t enable; uint8_t enable;
uint8_t type; uint8_t type;
} __packed; } __packed;
#define BT_HCI_OP_VS_READ_BUILD_INFO BT_OP(BT_OGF_VS, 0x0008) #define BT_HCI_OP_VS_READ_BUILD_INFO BT_OP(BT_OGF_VS, 0x0008)
struct bt_hci_rp_vs_read_build_info { struct bt_hci_rp_vs_read_build_info {
uint8_t status; uint8_t status;
uint8_t info[]; uint8_t info[];
} __packed; } __packed;
struct bt_hci_vs_static_addr { struct bt_hci_vs_static_addr {
bt_addr_t bdaddr; bt_addr_t bdaddr;
uint8_t ir[16]; uint8_t ir[16];
} __packed; } __packed;
#define BT_HCI_OP_VS_READ_STATIC_ADDRS BT_OP(BT_OGF_VS, 0x0009) #define BT_HCI_OP_VS_READ_STATIC_ADDRS BT_OP(BT_OGF_VS, 0x0009)
struct bt_hci_rp_vs_read_static_addrs { struct bt_hci_rp_vs_read_static_addrs {
uint8_t status; uint8_t status;
uint8_t num_addrs; uint8_t num_addrs;
struct bt_hci_vs_static_addr a[]; struct bt_hci_vs_static_addr a[];
} __packed; } __packed;
#define BT_HCI_OP_VS_READ_KEY_HIERARCHY_ROOTS BT_OP(BT_OGF_VS, 0x000a) #define BT_HCI_OP_VS_READ_KEY_HIERARCHY_ROOTS BT_OP(BT_OGF_VS, 0x000a)
struct bt_hci_rp_vs_read_key_hierarchy_roots { struct bt_hci_rp_vs_read_key_hierarchy_roots {
uint8_t status; uint8_t status;
uint8_t ir[16]; uint8_t ir[16];
uint8_t er[16]; uint8_t er[16];
} __packed; } __packed;
#define BT_HCI_OP_VS_READ_CHIP_TEMP BT_OP(BT_OGF_VS, 0x000b) #define BT_HCI_OP_VS_READ_CHIP_TEMP BT_OP(BT_OGF_VS, 0x000b)
struct bt_hci_rp_vs_read_chip_temp { struct bt_hci_rp_vs_read_chip_temp {
uint8_t status; uint8_t status;
int8_t temps; int8_t temps;
} __packed; } __packed;
struct bt_hci_vs_cmd { struct bt_hci_vs_cmd {
uint16_t vendor_id; uint16_t vendor_id;
uint16_t opcode_base; uint16_t opcode_base;
} __packed; } __packed;
#define BT_HCI_VS_VID_ANDROID 0x0001 #define BT_HCI_VS_VID_ANDROID 0x0001
#define BT_HCI_VS_VID_MICROSOFT 0x0002 #define BT_HCI_VS_VID_MICROSOFT 0x0002
#define BT_HCI_OP_VS_READ_HOST_STACK_CMDS BT_OP(BT_OGF_VS, 0x000c) #define BT_HCI_OP_VS_READ_HOST_STACK_CMDS BT_OP(BT_OGF_VS, 0x000c)
struct bt_hci_rp_vs_read_host_stack_cmds { struct bt_hci_rp_vs_read_host_stack_cmds {
uint8_t status; uint8_t status;
uint8_t num_cmds; uint8_t num_cmds;
struct bt_hci_vs_cmd c[]; struct bt_hci_vs_cmd c[];
} __packed; } __packed;
#define BT_HCI_VS_SCAN_REQ_REPORTS_DISABLED 0x00 #define BT_HCI_VS_SCAN_REQ_REPORTS_DISABLED 0x00
#define BT_HCI_VS_SCAN_REQ_REPORTS_ENABLED 0x01 #define BT_HCI_VS_SCAN_REQ_REPORTS_ENABLED 0x01
#define BT_HCI_OP_VS_SET_SCAN_REQ_REPORTS BT_OP(BT_OGF_VS, 0x000d) #define BT_HCI_OP_VS_SET_SCAN_REQ_REPORTS BT_OP(BT_OGF_VS, 0x000d)
struct bt_hci_cp_vs_set_scan_req_reports { struct bt_hci_cp_vs_set_scan_req_reports {
uint8_t enable; uint8_t enable;
} __packed; } __packed;
#define BT_HCI_VS_LL_HANDLE_TYPE_ADV 0x00 #define BT_HCI_VS_LL_HANDLE_TYPE_ADV 0x00
@ -159,37 +159,37 @@ struct bt_hci_cp_vs_set_scan_req_reports {
#define BT_HCI_VS_LL_TX_POWER_LEVEL_NO_PREF 0x7F #define BT_HCI_VS_LL_TX_POWER_LEVEL_NO_PREF 0x7F
#define BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL BT_OP(BT_OGF_VS, 0x000e) #define BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL BT_OP(BT_OGF_VS, 0x000e)
struct bt_hci_cp_vs_write_tx_power_level { struct bt_hci_cp_vs_write_tx_power_level {
uint8_t handle_type; uint8_t handle_type;
uint16_t handle; uint16_t handle;
int8_t tx_power_level; int8_t tx_power_level;
} __packed; } __packed;
struct bt_hci_rp_vs_write_tx_power_level { struct bt_hci_rp_vs_write_tx_power_level {
uint8_t status; uint8_t status;
uint8_t handle_type; uint8_t handle_type;
uint16_t handle; uint16_t handle;
int8_t selected_tx_power; int8_t selected_tx_power;
} __packed; } __packed;
#define BT_HCI_OP_VS_READ_TX_POWER_LEVEL BT_OP(BT_OGF_VS, 0x000f) #define BT_HCI_OP_VS_READ_TX_POWER_LEVEL BT_OP(BT_OGF_VS, 0x000f)
struct bt_hci_cp_vs_read_tx_power_level { struct bt_hci_cp_vs_read_tx_power_level {
uint8_t handle_type; uint8_t handle_type;
uint16_t handle; uint16_t handle;
} __packed; } __packed;
struct bt_hci_rp_vs_read_tx_power_level { struct bt_hci_rp_vs_read_tx_power_level {
uint8_t status; uint8_t status;
uint8_t handle_type; uint8_t handle_type;
uint16_t handle; uint16_t handle;
int8_t tx_power_level; int8_t tx_power_level;
} __packed; } __packed;
#define BT_HCI_OP_VS_READ_USB_TRANSPORT_MODE BT_OP(BT_OGF_VS, 0x0010) #define BT_HCI_OP_VS_READ_USB_TRANSPORT_MODE BT_OP(BT_OGF_VS, 0x0010)
struct bt_hci_rp_vs_read_usb_transport_mode { struct bt_hci_rp_vs_read_usb_transport_mode {
uint8_t status; uint8_t status;
uint8_t num_supported_modes; uint8_t num_supported_modes;
uint8_t supported_mode[]; uint8_t supported_mode[];
} __packed; } __packed;
#define BT_HCI_VS_USB_H2_MODE 0x00 #define BT_HCI_VS_USB_H2_MODE 0x00
@ -198,19 +198,19 @@ struct bt_hci_rp_vs_read_usb_transport_mode {
#define BT_HCI_OP_VS_SET_USB_TRANSPORT_MODE BT_OP(BT_OGF_VS, 0x0011) #define BT_HCI_OP_VS_SET_USB_TRANSPORT_MODE BT_OP(BT_OGF_VS, 0x0011)
struct bt_hci_cp_vs_set_usb_transport_mode { struct bt_hci_cp_vs_set_usb_transport_mode {
uint8_t mode; uint8_t mode;
} __packed; } __packed;
/* Events */ /* Events */
struct bt_hci_evt_vs { struct bt_hci_evt_vs {
uint8_t subevent; uint8_t subevent;
} __packed; } __packed;
#define BT_HCI_EVT_VS_FATAL_ERROR 0x02 #define BT_HCI_EVT_VS_FATAL_ERROR 0x02
struct bt_hci_evt_vs_fatal_error { struct bt_hci_evt_vs_fatal_error {
uint64_t pc; uint64_t pc;
uint8_t err_info[]; uint8_t err_info[];
} __packed; } __packed;
#define BT_HCI_VS_TRACE_LMP_TX 0x01 #define BT_HCI_VS_TRACE_LMP_TX 0x01
@ -220,14 +220,14 @@ struct bt_hci_evt_vs_fatal_error {
#define BT_HCI_VS_TRACE_LE_CONN_IND 0x05 #define BT_HCI_VS_TRACE_LE_CONN_IND 0x05
#define BT_HCI_EVT_VS_TRACE_INFO 0x03 #define BT_HCI_EVT_VS_TRACE_INFO 0x03
struct bt_hci_evt_vs_trace_info { struct bt_hci_evt_vs_trace_info {
uint8_t type; uint8_t type;
uint8_t data[]; uint8_t data[];
} __packed; } __packed;
#define BT_HCI_EVT_VS_SCAN_REQ_RX 0x04 #define BT_HCI_EVT_VS_SCAN_REQ_RX 0x04
struct bt_hci_evt_vs_scan_req_rx { struct bt_hci_evt_vs_scan_req_rx {
bt_addr_le_t addr; bt_addr_le_t addr;
int8_t rssi; int8_t rssi;
} __packed; } __packed;
/* Event mask bits */ /* Event mask bits */
@ -243,133 +243,133 @@ struct bt_hci_evt_vs_scan_req_rx {
#define BT_HCI_MESH_EVT_PREFIX 0xF0 #define BT_HCI_MESH_EVT_PREFIX 0xF0
struct bt_hci_cp_mesh { struct bt_hci_cp_mesh {
uint8_t opcode; uint8_t opcode;
} __packed; } __packed;
#define BT_HCI_OC_MESH_GET_OPTS 0x00 #define BT_HCI_OC_MESH_GET_OPTS 0x00
struct bt_hci_rp_mesh_get_opts { struct bt_hci_rp_mesh_get_opts {
uint8_t status; uint8_t status;
uint8_t opcode; uint8_t opcode;
uint8_t revision; uint8_t revision;
uint8_t ch_map; uint8_t ch_map;
int8_t min_tx_power; int8_t min_tx_power;
int8_t max_tx_power; int8_t max_tx_power;
uint8_t max_scan_filter; uint8_t max_scan_filter;
uint8_t max_filter_pattern; uint8_t max_filter_pattern;
uint8_t max_adv_slot; uint8_t max_adv_slot;
uint8_t max_tx_window; uint8_t max_tx_window;
uint8_t evt_prefix_len; uint8_t evt_prefix_len;
uint8_t evt_prefix; uint8_t evt_prefix;
} __packed; } __packed;
#define BT_HCI_MESH_PATTERN_LEN_MAX 0x0f #define BT_HCI_MESH_PATTERN_LEN_MAX 0x0f
#define BT_HCI_OC_MESH_SET_SCAN_FILTER 0x01 #define BT_HCI_OC_MESH_SET_SCAN_FILTER 0x01
struct bt_hci_mesh_pattern { struct bt_hci_mesh_pattern {
uint8_t pattern_len; uint8_t pattern_len;
uint8_t pattern[]; uint8_t pattern[];
} __packed; } __packed;
struct bt_hci_cp_mesh_set_scan_filter { struct bt_hci_cp_mesh_set_scan_filter {
uint8_t scan_filter; uint8_t scan_filter;
uint8_t filter_dup; uint8_t filter_dup;
uint8_t num_patterns; uint8_t num_patterns;
struct bt_hci_mesh_pattern patterns[]; struct bt_hci_mesh_pattern patterns[];
} __packed; } __packed;
struct bt_hci_rp_mesh_set_scan_filter { struct bt_hci_rp_mesh_set_scan_filter {
uint8_t status; uint8_t status;
uint8_t opcode; uint8_t opcode;
uint8_t scan_filter; uint8_t scan_filter;
} __packed; } __packed;
#define BT_HCI_OC_MESH_ADVERTISE 0x02 #define BT_HCI_OC_MESH_ADVERTISE 0x02
struct bt_hci_cp_mesh_advertise { struct bt_hci_cp_mesh_advertise {
uint8_t adv_slot; uint8_t adv_slot;
uint8_t own_addr_type; uint8_t own_addr_type;
bt_addr_t random_addr; bt_addr_t random_addr;
uint8_t ch_map; uint8_t ch_map;
int8_t tx_power; int8_t tx_power;
uint8_t min_tx_delay; uint8_t min_tx_delay;
uint8_t max_tx_delay; uint8_t max_tx_delay;
uint8_t retx_count; uint8_t retx_count;
uint8_t retx_interval; uint8_t retx_interval;
uint8_t scan_delay; uint8_t scan_delay;
uint16_t scan_duration; uint16_t scan_duration;
uint8_t scan_filter; uint8_t scan_filter;
uint8_t data_len; uint8_t data_len;
uint8_t data[31]; uint8_t data[31];
} __packed; } __packed;
struct bt_hci_rp_mesh_advertise { struct bt_hci_rp_mesh_advertise {
uint8_t status; uint8_t status;
uint8_t opcode; uint8_t opcode;
uint8_t adv_slot; uint8_t adv_slot;
} __packed; } __packed;
#define BT_HCI_OC_MESH_ADVERTISE_TIMED 0x03 #define BT_HCI_OC_MESH_ADVERTISE_TIMED 0x03
struct bt_hci_cp_mesh_advertise_timed { struct bt_hci_cp_mesh_advertise_timed {
uint8_t adv_slot; uint8_t adv_slot;
uint8_t own_addr_type; uint8_t own_addr_type;
bt_addr_t random_addr; bt_addr_t random_addr;
uint8_t ch_map; uint8_t ch_map;
int8_t tx_power; int8_t tx_power;
uint8_t retx_count; uint8_t retx_count;
uint8_t retx_interval; uint8_t retx_interval;
uint32_t instant; uint32_t instant;
uint16_t tx_delay; uint16_t tx_delay;
uint16_t tx_window; uint16_t tx_window;
uint8_t data_len; uint8_t data_len;
uint8_t data[31]; uint8_t data[31];
} __packed; } __packed;
struct bt_hci_rp_mesh_advertise_timed { struct bt_hci_rp_mesh_advertise_timed {
uint8_t status; uint8_t status;
uint8_t opcode; uint8_t opcode;
uint8_t adv_slot; uint8_t adv_slot;
} __packed; } __packed;
#define BT_HCI_OC_MESH_ADVERTISE_CANCEL 0x04 #define BT_HCI_OC_MESH_ADVERTISE_CANCEL 0x04
struct bt_hci_cp_mesh_advertise_cancel { struct bt_hci_cp_mesh_advertise_cancel {
uint8_t adv_slot; uint8_t adv_slot;
} __packed; } __packed;
struct bt_hci_rp_mesh_advertise_cancel { struct bt_hci_rp_mesh_advertise_cancel {
uint8_t status; uint8_t status;
uint8_t opcode; uint8_t opcode;
uint8_t adv_slot; uint8_t adv_slot;
} __packed; } __packed;
#define BT_HCI_OC_MESH_SET_SCANNING 0x05 #define BT_HCI_OC_MESH_SET_SCANNING 0x05
struct bt_hci_cp_mesh_set_scanning { struct bt_hci_cp_mesh_set_scanning {
uint8_t enable; uint8_t enable;
uint8_t ch_map; uint8_t ch_map;
uint8_t scan_filter; uint8_t scan_filter;
} __packed; } __packed;
struct bt_hci_rp_mesh_set_scanning { struct bt_hci_rp_mesh_set_scanning {
uint8_t status; uint8_t status;
uint8_t opcode; uint8_t opcode;
} __packed; } __packed;
/* Events */ /* Events */
struct bt_hci_evt_mesh { struct bt_hci_evt_mesh {
uint8_t prefix; uint8_t prefix;
uint8_t subevent; uint8_t subevent;
} __packed; } __packed;
#define BT_HCI_EVT_MESH_ADV_COMPLETE 0x00 #define BT_HCI_EVT_MESH_ADV_COMPLETE 0x00
struct bt_hci_evt_mesh_adv_complete { struct bt_hci_evt_mesh_adv_complete {
uint8_t adv_slot; uint8_t adv_slot;
} __packed; } __packed;
#define BT_HCI_EVT_MESH_SCANNING_REPORT 0x01 #define BT_HCI_EVT_MESH_SCANNING_REPORT 0x01
struct bt_hci_evt_mesh_scan_report { struct bt_hci_evt_mesh_scan_report {
bt_addr_le_t addr; bt_addr_le_t addr;
uint8_t chan; uint8_t chan;
int8_t rssi; int8_t rssi;
uint32_t instant; uint32_t instant;
uint8_t data_len; uint8_t data_len;
uint8_t data[]; uint8_t data[];
} __packed; } __packed;
struct bt_hci_evt_mesh_scanning_report { struct bt_hci_evt_mesh_scanning_report {
uint8_t num_reports; uint8_t num_reports;
struct bt_hci_evt_mesh_scan_report reports[]; struct bt_hci_evt_mesh_scan_report reports[];
} __packed; } __packed;
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -15,8 +15,8 @@
#include <string.h> #include <string.h>
enum l2cap_conn_list_action { enum l2cap_conn_list_action {
BT_L2CAP_CHAN_LOOKUP, BT_L2CAP_CHAN_LOOKUP,
BT_L2CAP_CHAN_DETACH, BT_L2CAP_CHAN_DETACH,
}; };
#define BT_L2CAP_CID_BR_SIG 0x0001 #define BT_L2CAP_CID_BR_SIG 0x0001
@ -28,14 +28,14 @@ enum l2cap_conn_list_action {
#define BT_L2CAP_PSM_RFCOMM 0x0003 #define BT_L2CAP_PSM_RFCOMM 0x0003
struct bt_l2cap_hdr { struct bt_l2cap_hdr {
uint16_t len; uint16_t len;
uint16_t cid; uint16_t cid;
} __packed; } __packed;
struct bt_l2cap_sig_hdr { struct bt_l2cap_sig_hdr {
uint8_t code; uint8_t code;
uint8_t ident; uint8_t ident;
uint16_t len; uint16_t len;
} __packed; } __packed;
#define BT_L2CAP_REJ_NOT_UNDERSTOOD 0x0000 #define BT_L2CAP_REJ_NOT_UNDERSTOOD 0x0000
@ -44,19 +44,19 @@ struct bt_l2cap_sig_hdr {
#define BT_L2CAP_CMD_REJECT 0x01 #define BT_L2CAP_CMD_REJECT 0x01
struct bt_l2cap_cmd_reject { struct bt_l2cap_cmd_reject {
uint16_t reason; uint16_t reason;
uint8_t data[]; uint8_t data[];
} __packed; } __packed;
struct bt_l2cap_cmd_reject_cid_data { struct bt_l2cap_cmd_reject_cid_data {
uint16_t scid; uint16_t scid;
uint16_t dcid; uint16_t dcid;
} __packed; } __packed;
#define BT_L2CAP_CONN_REQ 0x02 #define BT_L2CAP_CONN_REQ 0x02
struct bt_l2cap_conn_req { struct bt_l2cap_conn_req {
uint16_t psm; uint16_t psm;
uint16_t scid; uint16_t scid;
} __packed; } __packed;
/* command statuses in reposnse */ /* command statuses in reposnse */
@ -74,10 +74,10 @@ struct bt_l2cap_conn_req {
#define BT_L2CAP_CONN_RSP 0x03 #define BT_L2CAP_CONN_RSP 0x03
struct bt_l2cap_conn_rsp { struct bt_l2cap_conn_rsp {
uint16_t dcid; uint16_t dcid;
uint16_t scid; uint16_t scid;
uint16_t result; uint16_t result;
uint16_t status; uint16_t status;
} __packed; } __packed;
#define BT_L2CAP_CONF_SUCCESS 0x0000 #define BT_L2CAP_CONF_SUCCESS 0x0000
@ -86,17 +86,17 @@ struct bt_l2cap_conn_rsp {
#define BT_L2CAP_CONF_REQ 0x04 #define BT_L2CAP_CONF_REQ 0x04
struct bt_l2cap_conf_req { struct bt_l2cap_conf_req {
uint16_t dcid; uint16_t dcid;
uint16_t flags; uint16_t flags;
uint8_t data[]; uint8_t data[];
} __packed; } __packed;
#define BT_L2CAP_CONF_RSP 0x05 #define BT_L2CAP_CONF_RSP 0x05
struct bt_l2cap_conf_rsp { struct bt_l2cap_conf_rsp {
uint16_t scid; uint16_t scid;
uint16_t flags; uint16_t flags;
uint16_t result; uint16_t result;
uint8_t data[]; uint8_t data[];
} __packed; } __packed;
/* Option type used by MTU config request data */ /* Option type used by MTU config request data */
@ -106,21 +106,21 @@ struct bt_l2cap_conf_rsp {
#define BT_L2CAP_CONF_MASK 0x7f #define BT_L2CAP_CONF_MASK 0x7f
struct bt_l2cap_conf_opt { struct bt_l2cap_conf_opt {
uint8_t type; uint8_t type;
uint8_t len; uint8_t len;
uint8_t data[]; uint8_t data[];
} __packed; } __packed;
#define BT_L2CAP_DISCONN_REQ 0x06 #define BT_L2CAP_DISCONN_REQ 0x06
struct bt_l2cap_disconn_req { struct bt_l2cap_disconn_req {
uint16_t dcid; uint16_t dcid;
uint16_t scid; uint16_t scid;
} __packed; } __packed;
#define BT_L2CAP_DISCONN_RSP 0x07 #define BT_L2CAP_DISCONN_RSP 0x07
struct bt_l2cap_disconn_rsp { struct bt_l2cap_disconn_rsp {
uint16_t dcid; uint16_t dcid;
uint16_t scid; uint16_t scid;
} __packed; } __packed;
#define BT_L2CAP_INFO_FEAT_MASK 0x0002 #define BT_L2CAP_INFO_FEAT_MASK 0x0002
@ -128,7 +128,7 @@ struct bt_l2cap_disconn_rsp {
#define BT_L2CAP_INFO_REQ 0x0a #define BT_L2CAP_INFO_REQ 0x0a
struct bt_l2cap_info_req { struct bt_l2cap_info_req {
uint16_t type; uint16_t type;
} __packed; } __packed;
/* info result */ /* info result */
@ -137,17 +137,17 @@ struct bt_l2cap_info_req {
#define BT_L2CAP_INFO_RSP 0x0b #define BT_L2CAP_INFO_RSP 0x0b
struct bt_l2cap_info_rsp { struct bt_l2cap_info_rsp {
uint16_t type; uint16_t type;
uint16_t result; uint16_t result;
uint8_t data[]; uint8_t data[];
} __packed; } __packed;
#define BT_L2CAP_CONN_PARAM_REQ 0x12 #define BT_L2CAP_CONN_PARAM_REQ 0x12
struct bt_l2cap_conn_param_req { struct bt_l2cap_conn_param_req {
uint16_t min_interval; uint16_t min_interval;
uint16_t max_interval; uint16_t max_interval;
uint16_t latency; uint16_t latency;
uint16_t timeout; uint16_t timeout;
} __packed; } __packed;
#define BT_L2CAP_CONN_PARAM_ACCEPTED 0x0000 #define BT_L2CAP_CONN_PARAM_ACCEPTED 0x0000
@ -155,16 +155,16 @@ struct bt_l2cap_conn_param_req {
#define BT_L2CAP_CONN_PARAM_RSP 0x13 #define BT_L2CAP_CONN_PARAM_RSP 0x13
struct bt_l2cap_conn_param_rsp { struct bt_l2cap_conn_param_rsp {
uint16_t result; uint16_t result;
} __packed; } __packed;
#define BT_L2CAP_LE_CONN_REQ 0x14 #define BT_L2CAP_LE_CONN_REQ 0x14
struct bt_l2cap_le_conn_req { struct bt_l2cap_le_conn_req {
uint16_t psm; uint16_t psm;
uint16_t scid; uint16_t scid;
uint16_t mtu; uint16_t mtu;
uint16_t mps; uint16_t mps;
uint16_t credits; uint16_t credits;
} __packed; } __packed;
/* valid results in conn response on LE */ /* valid results in conn response on LE */
@ -182,42 +182,42 @@ struct bt_l2cap_le_conn_req {
#define BT_L2CAP_LE_CONN_RSP 0x15 #define BT_L2CAP_LE_CONN_RSP 0x15
struct bt_l2cap_le_conn_rsp { struct bt_l2cap_le_conn_rsp {
uint16_t dcid; uint16_t dcid;
uint16_t mtu; uint16_t mtu;
uint16_t mps; uint16_t mps;
uint16_t credits; uint16_t credits;
uint16_t result; uint16_t result;
} __packed; } __packed;
#define BT_L2CAP_LE_CREDITS 0x16 #define BT_L2CAP_LE_CREDITS 0x16
struct bt_l2cap_le_credits { struct bt_l2cap_le_credits {
uint16_t cid; uint16_t cid;
uint16_t credits; uint16_t credits;
} __packed; } __packed;
#define BT_L2CAP_ECRED_CONN_REQ 0x17 #define BT_L2CAP_ECRED_CONN_REQ 0x17
struct bt_l2cap_ecred_conn_req { struct bt_l2cap_ecred_conn_req {
uint16_t psm; uint16_t psm;
uint16_t mtu; uint16_t mtu;
uint16_t mps; uint16_t mps;
uint16_t credits; uint16_t credits;
uint16_t scid[]; uint16_t scid[];
} __packed; } __packed;
#define BT_L2CAP_ECRED_CONN_RSP 0x18 #define BT_L2CAP_ECRED_CONN_RSP 0x18
struct bt_l2cap_ecred_conn_rsp { struct bt_l2cap_ecred_conn_rsp {
uint16_t mtu; uint16_t mtu;
uint16_t mps; uint16_t mps;
uint16_t credits; uint16_t credits;
uint16_t result; uint16_t result;
uint16_t dcid[]; uint16_t dcid[];
} __packed; } __packed;
#define BT_L2CAP_ECRED_RECONF_REQ 0x19 #define BT_L2CAP_ECRED_RECONF_REQ 0x19
struct bt_l2cap_ecred_reconf_req { struct bt_l2cap_ecred_reconf_req {
uint16_t mtu; uint16_t mtu;
uint16_t mps; uint16_t mps;
uint16_t scid[]; uint16_t scid[];
} __packed; } __packed;
#define BT_L2CAP_RECONF_SUCCESS 0x0000 #define BT_L2CAP_RECONF_SUCCESS 0x0000
@ -226,5 +226,5 @@ struct bt_l2cap_ecred_reconf_req {
#define BT_L2CAP_ECRED_RECONF_RSP 0x1a #define BT_L2CAP_ECRED_RECONF_RSP 0x1a
struct bt_l2cap_ecred_reconf_rsp { struct bt_l2cap_ecred_reconf_rsp {
uint16_t result; uint16_t result;
} __packed; } __packed;

View file

@ -18,7 +18,7 @@ Start libraries with the cookiecutter
Cookiecutter is a tool that lets you bootstrap a new repo based on another repo. Cookiecutter is a tool that lets you bootstrap a new repo based on another repo.
We've made one `here <https://github.com/adafruit/cookiecutter-adafruit-circuitpython>`_ We've made one `here <https://github.com/adafruit/cookiecutter-adafruit-circuitpython>`_
for CircuitPython libraries that include configs for Travis CI and ReadTheDocs for CircuitPython libraries that include configs for Travis CI and ReadTheDocs
along with a setup.py, license, code of conduct and readme. along with a setup.py, license, code of conduct, readme among other files.
.. code-block::sh .. code-block::sh
@ -165,6 +165,24 @@ use what.
Here is more info on properties from Here is more info on properties from
`Python <https://docs.python.org/3/library/functions.html#property>`_. `Python <https://docs.python.org/3/library/functions.html#property>`_.
Exceptions and asserts
--------------------------------------------------------------------------------
Raise an appropriate `Exception <https://docs.python.org/3/library/exceptions.html#bltin-exceptions>`_,
along with a useful message, whenever a critical test or other condition fails.
Example::
if not 0 <= pin <= 7:
raise ValueError("Pin number must be 0-7.")
If memory is constrained and a more compact method is needed, use `assert`
instead.
Example::
assert 0 <= pin <= 7, "Pin number must be 0-7."
Design for compatibility with CPython Design for compatibility with CPython
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -234,7 +252,7 @@ At the class level document what class does and how to initialize it::
"""DS3231 real-time clock. """DS3231 real-time clock.
:param ~busio.I2C i2c_bus: The I2C bus the DS3231 is connected to. :param ~busio.I2C i2c_bus: The I2C bus the DS3231 is connected to.
:param int address: The I2C address of the device. :param int address: The I2C address of the device. Defaults to :const:`0x40`
""" """
def __init__(self, i2c_bus, address=0x40): def __init__(self, i2c_bus, address=0x40):
@ -249,7 +267,7 @@ Renders as:
DS3231 real-time clock. DS3231 real-time clock.
:param ~busio.I2C i2c_bus: The I2C bus the DS3231 is connected to. :param ~busio.I2C i2c_bus: The I2C bus the DS3231 is connected to.
:param int address: The I2C address of the device. :param int address: The I2C address of the device. Defaults to :const:`0x40`
Attributes Attributes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -498,6 +516,15 @@ when using ``const()``, keep in mind these general guide lines:
- If user will not need access to variable, prefix name with a leading - If user will not need access to variable, prefix name with a leading
underscore, ex: ``_SOME_CONST``. underscore, ex: ``_SOME_CONST``.
Libraries Examples
------------------
When adding examples, cookiecutter will add a ``<name>_simpletest.py`` file in the examples directory for you.
Be sure to include code with the library minimal functionalities to work on a device.
You could other examples if needed featuring different
functionalities of the library.
If you add additional examples, be sure to include them in the ``examples.rst``. Naming of the examples
files should use the name of the library followed by a description, using underscore to separate them.
Sensor properties and units Sensor properties and units
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -518,7 +545,7 @@ properties.
+-----------------------+-----------------------+-------------------------------------------------------------------------+ +-----------------------+-----------------------+-------------------------------------------------------------------------+
| ``gyro`` | (float, float, float) | x, y, z radians per second | | ``gyro`` | (float, float, float) | x, y, z radians per second |
+-----------------------+-----------------------+-------------------------------------------------------------------------+ +-----------------------+-----------------------+-------------------------------------------------------------------------+
| ``temperature`` | float | degrees centigrade | | ``temperature`` | float | degrees Celsius |
+-----------------------+-----------------------+-------------------------------------------------------------------------+ +-----------------------+-----------------------+-------------------------------------------------------------------------+
| ``CO2`` | float | measured CO2 in ppm | | ``CO2`` | float | measured CO2 in ppm |
+-----------------------+-----------------------+-------------------------------------------------------------------------+ +-----------------------+-----------------------+-------------------------------------------------------------------------+
@ -526,9 +553,9 @@ properties.
+-----------------------+-----------------------+-------------------------------------------------------------------------+ +-----------------------+-----------------------+-------------------------------------------------------------------------+
| ``TVOC`` | float | Total Volatile Organic Compounds in ppb | | ``TVOC`` | float | Total Volatile Organic Compounds in ppb |
+-----------------------+-----------------------+-------------------------------------------------------------------------+ +-----------------------+-----------------------+-------------------------------------------------------------------------+
| ``distance`` | float | centimeters | | ``distance`` | float | centimeters (cm) |
+-----------------------+-----------------------+-------------------------------------------------------------------------+ +-----------------------+-----------------------+-------------------------------------------------------------------------+
| ``proximity`` | int | non-unit-specifc proximity values (monotonic but not actual distance) | | ``proximity`` | int | non-unit-specific proximity values (monotonic but not actual distance) |
+-----------------------+-----------------------+-------------------------------------------------------------------------+ +-----------------------+-----------------------+-------------------------------------------------------------------------+
| ``light`` | float | non-unit-specific light levels (should be monotonic but is not lux) | | ``light`` | float | non-unit-specific light levels (should be monotonic but is not lux) |
+-----------------------+-----------------------+-------------------------------------------------------------------------+ +-----------------------+-----------------------+-------------------------------------------------------------------------+
@ -550,7 +577,7 @@ properties.
+-----------------------+-----------------------+-------------------------------------------------------------------------+ +-----------------------+-----------------------+-------------------------------------------------------------------------+
| ``duty_cycle`` | int | 16-bit PWM duty cycle (regardless of output resolution) | | ``duty_cycle`` | int | 16-bit PWM duty cycle (regardless of output resolution) |
+-----------------------+-----------------------+-------------------------------------------------------------------------+ +-----------------------+-----------------------+-------------------------------------------------------------------------+
| ``frequency`` | int | Hertz | | ``frequency`` | int | Hertz (Hz) |
+-----------------------+-----------------------+-------------------------------------------------------------------------+ +-----------------------+-----------------------+-------------------------------------------------------------------------+
| ``value`` | bool | Digital logic | | ``value`` | bool | Digital logic |
+-----------------------+-----------------------+-------------------------------------------------------------------------+ +-----------------------+-----------------------+-------------------------------------------------------------------------+
@ -574,9 +601,8 @@ mimic the structure in ``shared-bindings``.
To test your native modules or core enhancements, follow these Adafruit Learning Guides To test your native modules or core enhancements, follow these Adafruit Learning Guides
for building local firmware to flash onto your device(s): for building local firmware to flash onto your device(s):
`SAMD21 - Build Firmware Learning Guide <https://learn.adafruit.com/micropython-for-samd21/build-firmware>`_ `Build CircuitPython <https://learn.adafruit.com/building-circuitpython>`_
`ESP8266 - Build Firmware Learning Guide <https://learn.adafruit.com/building-and-running-micropython-on-the-esp8266/overview>`_
MicroPython compatibility MicroPython compatibility
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View file

@ -46,6 +46,7 @@ Full Table of Contents
../BUILDING ../BUILDING
../CODE_OF_CONDUCT ../CODE_OF_CONDUCT
../license.rst ../license.rst
../WEBUSB_README
Indices and tables Indices and tables
================== ==================

View file

@ -14,6 +14,33 @@ hold/accumulate various objects.
Classes Classes
------- -------
.. function:: deque(iterable, maxlen[, flags])
Deques (double-ended queues) are a list-like container that support O(1)
appends and pops from either side of the deque. New deques are created
using the following arguments:
- *iterable* must be the empty tuple, and the new deque is created empty.
- *maxlen* must be specified and the deque will be bounded to this
maximum length. Once the deque is full, any new items added will
discard items from the opposite end.
- 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
methods:
.. method:: deque.append(x)
Add *x* to the right side of the deque.
Raises IndexError if overflow checking is enabled and there is no more room left.
.. method:: deque.popleft()
Remove and return an item from the left side of the deque.
Raises IndexError if no items are present.
.. function:: namedtuple(name, fields) .. function:: namedtuple(name, fields)
This is factory function to create a new namedtuple type with a specific This is factory function to create a new namedtuple type with a specific

View file

@ -39,8 +39,6 @@ with the ``u`` prefix dropped:
sys.rst sys.rst
uctypes.rst uctypes.rst
uselect.rst uselect.rst
usocket.rst
ussl.rst
uzlib.rst uzlib.rst
Omitted functions in the ``string`` library Omitted functions in the ``string`` library

View file

@ -81,6 +81,9 @@ Functions
in a row and the lock-depth will increase, and then `heap_unlock()` must be in a row and the lock-depth will increase, and then `heap_unlock()` must be
called the same number of times to make the heap available again. called the same number of times to make the heap available again.
If the REPL becomes active with the heap locked then it will be forcefully
unlocked.
.. function:: kbd_intr(chr) .. function:: kbd_intr(chr)
Set the character that will raise a `KeyboardInterrupt` exception. By Set the character that will raise a `KeyboardInterrupt` exception. By

View file

@ -10,41 +10,101 @@ This module implements regular expression operations. Regular expression
syntax supported is a subset of CPython ``re`` module (and actually is syntax supported is a subset of CPython ``re`` module (and actually is
a subset of POSIX extended regular expressions). a subset of POSIX extended regular expressions).
Supported operators are: Supported operators and special sequences are:
``'.'`` ``.``
Match any character. Match any character.
``'[...]'`` ``[...]``
Match set of characters. Individual characters and ranges are supported, Match set of characters. Individual characters and ranges are supported,
including negated sets (e.g. ``[^a-c]``). including negated sets (e.g. ``[^a-c]``).
``'^'`` ``^``
Match the start of the string.
``'$'`` ``$``
Match the end of the string.
``'?'`` ``?``
Match zero or one of the previous sub-pattern.
``'*'`` ``*``
Match zero or more of the previous sub-pattern.
``'+'`` ``+``
Match one or more of the previous sub-pattern.
``'??'`` ``??``
Non-greedy version of ``?``, match zero or one, with the preference
for zero.
``'*?'`` ``*?``
Non-greedy version of ``*``, match zero or more, with the preference
for the shortest match.
``'+?'`` ``+?``
Non-greedy version of ``+``, match one or more, with the preference
for the shortest match.
``'|'`` ``|``
Match either the left-hand side or the right-hand side sub-patterns of
this operator.
``'(...)'`` ``(...)``
Grouping. Each group is capturing (a substring it captures can be accessed Grouping. Each group is capturing (a substring it captures can be accessed
with `match.group()` method). with `match.group()` method).
**NOT SUPPORTED**: Counted repetitions (``{m,n}``), more advanced assertions ``\d``
(``\b``, ``\B``), named groups (``(?P<name>...)``), non-capturing groups Matches digit. Equivalent to ``[0-9]``.
(``(?:...)``), etc.
``\D``
Matches non-digit. Equivalent to ``[^0-9]``.
``\s``
Matches whitespace. Equivalent to ``[ \t-\r]``.
``\S``
Matches non-whitespace. Equivalent to ``[^ \t-\r]``.
``\w``
Matches "word characters" (ASCII only). Equivalent to ``[A-Za-z0-9_]``.
``\W``
Matches non "word characters" (ASCII only). Equivalent to ``[^A-Za-z0-9_]``.
``\``
Escape character. Any other character following the backslash, except
for those listed above, is taken literally. For example, ``\*`` is
equivalent to literal ``*`` (not treated as the ``*`` operator).
Note that ``\r``, ``\n``, etc. are not handled specially, and will be
equivalent to literal letters ``r``, ``n``, etc. Due to this, it's
not recommended to use raw Python strings (``r""``) for regular
expressions. For example, ``r"\r\n"`` when used as the regular
expression is equivalent to ``"rn"``. To match CR character followed
by LF, use ``"\r\n"``.
**NOT SUPPORTED**:
* counted repetitions (``{m,n}``)
* named groups (``(?P<name>...)``)
* non-capturing groups (``(?:...)``)
* more advanced assertions (``\b``, ``\B``)
* special character escapes like ``\r``, ``\n`` - use Python's own escaping
instead
* etc.
Example::
import ure
# As ure doesn't support escapes itself, use of r"" strings is not
# recommended.
regex = ure.compile("[\r\n]")
regex.split("line1\rline2\nline3\r\n")
# Result:
# ['line1', 'line2', 'line3', '', '']
Functions Functions
--------- ---------
@ -64,6 +124,22 @@ Functions
string for first position which matches regex (which still may be string for first position which matches regex (which still may be
0 if regex is anchored). 0 if regex is anchored).
.. function:: sub(regex_str, replace, string, count=0, flags=0)
Compile *regex_str* and search for it in *string*, replacing all matches
with *replace*, and returning the new string.
*replace* can be a string or a function. If it is a string then escape
sequences of the form ``\<number>`` and ``\g<number>`` can be used to
expand to the corresponding group (or an empty string for unmatched groups).
If *replace* is a function then it must take a single argument (the match)
and should return a replacement string.
If *count* is specified and non-zero then substitution will stop after
this many substitutions are made. The *flags* argument is ignored.
Note: availability of this function depends on MicroPython port.
.. data:: DEBUG .. data:: DEBUG
Flag value, display debug information about compiled expression. Flag value, display debug information about compiled expression.
@ -79,8 +155,10 @@ Compiled regular expression. Instances of this class are created using
.. method:: regex.match(string) .. method:: regex.match(string)
regex.search(string) regex.search(string)
regex.sub(replace, string, count=0, flags=0)
Similar to the module-level functions :meth:`match` and :meth:`search`. Similar to the module-level functions :meth:`match`, :meth:`search`
and :meth:`sub`.
Using methods is (much) more efficient if the same regex is applied to Using methods is (much) more efficient if the same regex is applied to
multiple strings. multiple strings.
@ -93,9 +171,31 @@ Compiled regular expression. Instances of this class are created using
Match objects Match objects
------------- -------------
Match objects as returned by `match()` and `search()` methods. Match objects as returned by `match()` and `search()` methods, and passed
to the replacement function in `sub()`.
.. method:: match.group([index]) .. method:: match.group([index])
Return matching (sub)string. *index* is 0 for entire match, Return matching (sub)string. *index* is 0 for entire match,
1 and above for each capturing group. Only numeric groups are supported. 1 and above for each capturing group. Only numeric groups are supported.
.. method:: match.groups()
Return a tuple containing all the substrings of the groups of the match.
Note: availability of this method depends on MicroPython port.
.. method:: match.start([index])
match.end([index])
Return the index in the original string of the start or end of the
substring group that was matched. *index* defaults to the entire
group, otherwise it will select a group.
Note: availability of these methods depends on MicroPython port.
.. method:: match.span([index])
Returns the 2-tuple ``(match.start(index), match.end(index))``.
Note: availability of this method depends on MicroPython port.

View file

@ -13,19 +13,91 @@ module is to define data structure layout with about the same power as the
C language allows, and then access it using familiar dot-syntax to reference C language allows, and then access it using familiar dot-syntax to reference
sub-fields. sub-fields.
.. warning::
``uctypes`` module allows access to arbitrary memory addresses of the
machine (including I/O and control registers). Uncareful usage of it
may lead to crashes, data loss, and even hardware malfunction.
.. seealso:: .. seealso::
Module :mod:`struct` Module :mod:`struct`
Standard Python way to access binary data structures (doesn't scale Standard Python way to access binary data structures (doesn't scale
well to large and complex structures). well to large and complex structures).
Usage examples::
import uctypes
# Example 1: Subset of ELF file header
# https://wikipedia.org/wiki/Executable_and_Linkable_Format#File_header
ELF_HEADER = {
"EI_MAG": (0x0 | uctypes.ARRAY, 4 | uctypes.UINT8),
"EI_DATA": 0x5 | uctypes.UINT8,
"e_machine": 0x12 | uctypes.UINT16,
}
# "f" is an ELF file opened in binary mode
buf = f.read(uctypes.sizeof(ELF_HEADER, uctypes.LITTLE_ENDIAN))
header = uctypes.struct(uctypes.addressof(buf), ELF_HEADER, uctypes.LITTLE_ENDIAN)
assert header.EI_MAG == b"\x7fELF"
assert header.EI_DATA == 1, "Oops, wrong endianness. Could retry with uctypes.BIG_ENDIAN."
print("machine:", hex(header.e_machine))
# Example 2: In-memory data structure, with pointers
COORD = {
"x": 0 | uctypes.FLOAT32,
"y": 4 | uctypes.FLOAT32,
}
STRUCT1 = {
"data1": 0 | uctypes.UINT8,
"data2": 4 | uctypes.UINT32,
"ptr": (8 | uctypes.PTR, COORD),
}
# Suppose you have address of a structure of type STRUCT1 in "addr"
# uctypes.NATIVE is optional (used by default)
struct1 = uctypes.struct(addr, STRUCT1, uctypes.NATIVE)
print("x:", struct1.ptr[0].x)
# Example 3: Access to CPU registers. Subset of STM32F4xx WWDG block
WWDG_LAYOUT = {
"WWDG_CR": (0, {
# BFUINT32 here means size of the WWDG_CR register
"WDGA": 7 << uctypes.BF_POS | 1 << uctypes.BF_LEN | uctypes.BFUINT32,
"T": 0 << uctypes.BF_POS | 7 << uctypes.BF_LEN | uctypes.BFUINT32,
}),
"WWDG_CFR": (4, {
"EWI": 9 << uctypes.BF_POS | 1 << uctypes.BF_LEN | uctypes.BFUINT32,
"WDGTB": 7 << uctypes.BF_POS | 2 << uctypes.BF_LEN | uctypes.BFUINT32,
"W": 0 << uctypes.BF_POS | 7 << uctypes.BF_LEN | uctypes.BFUINT32,
}),
}
WWDG = uctypes.struct(0x40002c00, WWDG_LAYOUT)
WWDG.WWDG_CFR.WDGTB = 0b10
WWDG.WWDG_CR.WDGA = 1
print("Current counter:", WWDG.WWDG_CR.T)
Defining structure layout Defining structure layout
------------------------- -------------------------
Structure layout is defined by a "descriptor" - a Python dictionary which Structure layout is defined by a "descriptor" - a Python dictionary which
encodes field names as keys and other properties required to access them as encodes field names as keys and other properties required to access them as
associated values. Currently, uctypes requires explicit specification of associated values::
offsets for each field. Offset are given in bytes from a structure start.
{
"field1": <properties>,
"field2": <properties>,
...
}
Currently, ``uctypes`` requires explicit specification of offsets for each
field. Offset are given in bytes from the structure start.
Following are encoding examples for various field types: Following are encoding examples for various field types:
@ -33,7 +105,7 @@ Following are encoding examples for various field types:
"field_name": offset | uctypes.UINT32 "field_name": offset | uctypes.UINT32
in other words, value is scalar type identifier ORed with field offset in other words, the value is a scalar type identifier ORed with a field offset
(in bytes) from the start of the structure. (in bytes) from the start of the structure.
* Recursive structures:: * Recursive structures::
@ -43,9 +115,11 @@ Following are encoding examples for various field types:
"b1": 1 | uctypes.UINT8, "b1": 1 | uctypes.UINT8,
}) })
i.e. value is a 2-tuple, first element of which is offset, and second is i.e. value is a 2-tuple, first element of which is an offset, and second is
a structure descriptor dictionary (note: offsets in recursive descriptors a structure descriptor dictionary (note: offsets in recursive descriptors
are relative to the structure it defines). are relative to the structure it defines). Of course, recursive structures
can be specified not just by a literal dictionary, but by referring to a
structure descriptor dictionary (defined earlier) by name.
* Arrays of primitive types:: * Arrays of primitive types::
@ -53,42 +127,42 @@ Following are encoding examples for various field types:
i.e. value is a 2-tuple, first element of which is ARRAY flag ORed i.e. value is a 2-tuple, first element of which is ARRAY flag ORed
with offset, and second is scalar element type ORed number of elements with offset, and second is scalar element type ORed number of elements
in array. in the array.
* Arrays of aggregate types:: * Arrays of aggregate types::
"arr2": (offset | uctypes.ARRAY, size, {"b": 0 | uctypes.UINT8}), "arr2": (offset | uctypes.ARRAY, size, {"b": 0 | uctypes.UINT8}),
i.e. value is a 3-tuple, first element of which is ARRAY flag ORed i.e. value is a 3-tuple, first element of which is ARRAY flag ORed
with offset, second is a number of elements in array, and third is with offset, second is a number of elements in the array, and third is
descriptor of element type. a descriptor of element type.
* Pointer to a primitive type:: * Pointer to a primitive type::
"ptr": (offset | uctypes.PTR, uctypes.UINT8), "ptr": (offset | uctypes.PTR, uctypes.UINT8),
i.e. value is a 2-tuple, first element of which is PTR flag ORed i.e. value is a 2-tuple, first element of which is PTR flag ORed
with offset, and second is scalar element type. with offset, and second is a scalar element type.
* Pointer to an aggregate type:: * Pointer to an aggregate type::
"ptr2": (offset | uctypes.PTR, {"b": 0 | uctypes.UINT8}), "ptr2": (offset | uctypes.PTR, {"b": 0 | uctypes.UINT8}),
i.e. value is a 2-tuple, first element of which is PTR flag ORed i.e. value is a 2-tuple, first element of which is PTR flag ORed
with offset, second is descriptor of type pointed to. with offset, second is a descriptor of type pointed to.
* Bitfields:: * Bitfields::
"bitf0": offset | uctypes.BFUINT16 | lsbit << uctypes.BF_POS | bitsize << uctypes.BF_LEN, "bitf0": offset | uctypes.BFUINT16 | lsbit << uctypes.BF_POS | bitsize << uctypes.BF_LEN,
i.e. value is type of scalar value containing given bitfield (typenames are i.e. value is a type of scalar value containing given bitfield (typenames are
similar to scalar types, but prefixes with "BF"), ORed with offset for similar to scalar types, but prefixes with ``BF``), ORed with offset for
scalar value containing the bitfield, and further ORed with values for scalar value containing the bitfield, and further ORed with values for
bit offset and bit length of the bitfield within scalar value, shifted by bit position and bit length of the bitfield within the scalar value, shifted by
BF_POS and BF_LEN positions, respectively. Bitfield position is counted BF_POS and BF_LEN bits, respectively. A bitfield position is counted
from the least significant bit, and is the number of right-most bit of a from the least significant bit of the scalar (having position of 0), and
field (in other words, it's a number of bits a scalar needs to be shifted is the number of right-most bit of a field (in other words, it's a number
right to extract the bitfield). of bits a scalar needs to be shifted right to extract the bitfield).
In the example above, first a UINT16 value will be extracted at offset 0 In the example above, first a UINT16 value will be extracted at offset 0
(this detail may be important when accessing hardware registers, where (this detail may be important when accessing hardware registers, where
@ -128,10 +202,11 @@ Module contents
Layout type for a native structure - with data endianness and alignment Layout type for a native structure - with data endianness and alignment
conforming to the ABI of the system on which MicroPython runs. conforming to the ABI of the system on which MicroPython runs.
.. function:: sizeof(struct) .. function:: sizeof(struct, layout_type=NATIVE)
Return size of data structure in bytes. Argument can be either structure Return size of data structure in bytes. The *struct* argument can be
class or specific instantiated structure object (or its aggregate field). either a structure class or a specific instantiated structure object
(or its aggregate field).
.. function:: addressof(obj) .. function:: addressof(obj)
@ -153,6 +228,35 @@ Module contents
so it can be both written too, and you will access current value so it can be both written too, and you will access current value
at the given memory address. at the given memory address.
.. data:: UINT8
INT8
UINT16
INT16
UINT32
INT32
UINT64
INT64
Integer types for structure descriptors. Constants for 8, 16, 32,
and 64 bit types are provided, both signed and unsigned.
.. data:: FLOAT32
FLOAT64
Floating-point types for structure descriptors.
.. data:: VOID
``VOID`` is an alias for ``UINT8``, and is provided to conviniently define
C's void pointers: ``(uctypes.PTR, uctypes.VOID)``.
.. data:: PTR
ARRAY
Type constants for pointers and arrays. Note that there is no explicit
constant for structures, it's implicit: an aggregate type without ``PTR``
or ``ARRAY`` flags is a structure.
Structure descriptors and instantiating structure objects Structure descriptors and instantiating structure objects
--------------------------------------------------------- ---------------------------------------------------------
@ -165,7 +269,7 @@ following sources:
system. Lookup these addresses in datasheet for a particular MCU/SoC. system. Lookup these addresses in datasheet for a particular MCU/SoC.
* As a return value from a call to some FFI (Foreign Function Interface) * As a return value from a call to some FFI (Foreign Function Interface)
function. function.
* From uctypes.addressof(), when you want to pass arguments to an FFI * From `uctypes.addressof()`, when you want to pass arguments to an FFI
function, or alternatively, to access some data for I/O (for example, function, or alternatively, to access some data for I/O (for example,
data read from a file or network socket). data read from a file or network socket).
@ -183,30 +287,41 @@ the standard subscript operator ``[]`` - both read and assigned to.
If a field is a pointer, it can be dereferenced using ``[0]`` syntax If a field is a pointer, it can be dereferenced using ``[0]`` syntax
(corresponding to C ``*`` operator, though ``[0]`` works in C too). (corresponding to C ``*`` operator, though ``[0]`` works in C too).
Subscripting a pointer with other integer values but 0 are supported too, Subscripting a pointer with other integer values but 0 are also supported,
with the same semantics as in C. with the same semantics as in C.
Summing up, accessing structure fields generally follows C syntax, Summing up, accessing structure fields generally follows the C syntax,
except for pointer dereference, when you need to use ``[0]`` operator except for pointer dereference, when you need to use ``[0]`` operator
instead of ``*``. instead of ``*``.
Limitations Limitations
----------- -----------
Accessing non-scalar fields leads to allocation of intermediate objects 1. Accessing non-scalar fields leads to allocation of intermediate objects
to represent them. This means that special care should be taken to to represent them. This means that special care should be taken to
layout a structure which needs to be accessed when memory allocation layout a structure which needs to be accessed when memory allocation
is disabled (e.g. from an interrupt). The recommendations are: is disabled (e.g. from an interrupt). The recommendations are:
* Avoid nested structures. For example, instead of * Avoid accessing nested structures. For example, instead of
``mcu_registers.peripheral_a.register1``, define separate layout ``mcu_registers.peripheral_a.register1``, define separate layout
descriptors for each peripheral, to be accessed as descriptors for each peripheral, to be accessed as
``peripheral_a.register1``. ``peripheral_a.register1``. Or just cache a particular peripheral:
* Avoid other non-scalar data, like array. For example, instead of ``peripheral_a = mcu_registers.peripheral_a``. If a register
``peripheral_a.register[0]`` use ``peripheral_a.register0``. consists of multiple bitfields, you would need to cache references
to a particular register: ``reg_a = mcu_registers.peripheral_a.reg_a``.
* Avoid other non-scalar data, like arrays. For example, instead of
``peripheral_a.register[0]`` use ``peripheral_a.register0``. Again,
an alternative is to cache intermediate values, e.g.
``register0 = peripheral_a.register[0]``.
Note that these recommendations will lead to decreased readability 2. Range of offsets supported by the ``uctypes`` module is limited.
and conciseness of layouts, so they should be used only if the need The exact range supported is considered an implementation detail,
to access structure fields without allocation is anticipated (it's and the general suggestion is to split structure definitions to
even possible to define 2 parallel layouts - one for normal usage, cover from a few kilobytes to a few dozen of kilobytes maximum.
and a restricted one to use when memory allocation is prohibited). In most cases, this is a natural situation anyway, e.g. it doesn't make
sense to define all registers of an MCU (spread over 32-bit address
space) in one structure, but rather a peripheral block by peripheral
block. In some extreme cases, you may need to split a structure in
several parts artificially (e.g. if accessing native data structure
with multi-megabyte array in the middle, though that would be a very
synthetic case).

View file

@ -47,13 +47,18 @@ Methods
*eventmask* defaults to ``uselect.POLLIN | uselect.POLLOUT``. *eventmask* defaults to ``uselect.POLLIN | uselect.POLLOUT``.
It is OK to call this function multiple times for the same *obj*.
Successive calls will update *obj*'s eventmask to the value of
*eventmask* (i.e. will behave as `modify()`).
.. method:: poll.unregister(obj) .. method:: poll.unregister(obj)
Unregister *obj* from polling. Unregister *obj* from polling.
.. method:: poll.modify(obj, eventmask) .. method:: poll.modify(obj, eventmask)
Modify the *eventmask* for *obj*. Modify the *eventmask* for *obj*. If *obj* is not registered, `OSError`
is raised with error of ENOENT.
.. method:: poll.poll(timeout=-1) .. method:: poll.poll(timeout=-1)

View file

@ -1,336 +0,0 @@
*******************************
:mod:`usocket` -- socket module
*******************************
.. include:: ../templates/unsupported_in_circuitpython.inc
.. module:: usocket
:synopsis: socket module
|see_cpython_module| :mod:`cpython:socket`.
This module provides access to the BSD socket interface.
.. admonition:: Difference to CPython
:class: attention
For efficiency and consistency, socket objects in MicroPython implement a ``stream``
(file-like) interface directly. In CPython, you need to convert a socket to
a file-like object using `makefile()` method. This method is still supported
by MicroPython (but is a no-op), so where compatibility with CPython matters,
be sure to use it.
Socket address format(s)
------------------------
The native socket address format of the ``usocket`` module is an opaque data type
returned by `getaddrinfo` function, which must be used to resolve textual address
(including numeric addresses)::
sockaddr = usocket.getaddrinfo('www.micropython.org', 80)[0][-1]
# You must use getaddrinfo() even for numeric addresses
sockaddr = usocket.getaddrinfo('127.0.0.1', 80)[0][-1]
# Now you can use that address
sock.connect(addr)
Using `getaddrinfo` is the most efficient (both in terms of memory and processing
power) and portable way to work with addresses.
However, ``socket`` module (note the difference with native MicroPython
``usocket`` module described here) provides CPython-compatible way to specify
addresses using tuples, as described below.
Summing up:
* Always use `getaddrinfo` when writing portable applications.
* Tuple addresses described below can be used as a shortcut for
quick hacks and interactive use, if your port supports them.
Tuple address format for ``socket`` module:
* IPv4: *(ipv4_address, port)*, where *ipv4_address* is a string with
dot-notation numeric IPv4 address, e.g. ``"8.8.8.8"``, and *port* is and
integer port number in the range 1-65535. Note the domain names are not
accepted as *ipv4_address*, they should be resolved first using
`usocket.getaddrinfo()`.
* IPv6: *(ipv6_address, port, flowinfo, scopeid)*, where *ipv6_address*
is a string with colon-notation numeric IPv6 address, e.g. ``"2001:db8::1"``,
and *port* is an integer port number in the range 1-65535. *flowinfo*
must be 0. *scopeid* is the interface scope identifier for link-local
addresses. Note the domain names are not accepted as *ipv6_address*,
they should be resolved first using `usocket.getaddrinfo()`.
Functions
---------
.. function:: socket(af=AF_INET, type=SOCK_STREAM, proto=IPPROTO_TCP)
Create a new socket using the given address family, socket type and
protocol number. Note that specifying *proto* in most cases is not
required (and not recommended, as some MicroPython ports may omit
``IPPROTO_*`` constants). Instead, *type* argument will select needed
protocol automatically::
# Create STREAM TCP socket
socket(AF_INET, SOCK_STREAM)
# Create DGRAM UDP socket
socket(AF_INET, SOCK_DGRAM)
.. function:: getaddrinfo(host, port)
Translate the host/port argument into a sequence of 5-tuples that contain all the
necessary arguments for creating a socket connected to that service. The list of
5-tuples has following structure::
(family, type, proto, canonname, sockaddr)
The following example shows how to connect to a given url::
s = usocket.socket()
s.connect(usocket.getaddrinfo('www.micropython.org', 80)[0][-1])
.. admonition:: Difference to CPython
:class: attention
CPython raises a ``socket.gaierror`` exception (`OSError` subclass) in case
of error in this function. MicroPython doesn't have ``socket.gaierror``
and raises OSError directly. Note that error numbers of `getaddrinfo()`
form a separate namespace and may not match error numbers from
:py:mod:`uerrno` module. To distinguish `getaddrinfo()` errors, they are
represented by negative numbers, whereas standard system errors are
positive numbers (error numbers are accessible using ``e.args[0]`` property
from an exception object). The use of negative values is a provisional
detail which may change in the future.
.. function:: inet_ntop(af, bin_addr)
Convert a binary network address *bin_addr* of the given address family *af*
to a textual representation::
>>> usocket.inet_ntop(usocket.AF_INET, b"\x7f\0\0\1")
'127.0.0.1'
.. function:: inet_pton(af, txt_addr)
Convert a textual network address *txt_addr* of the given address family *af*
to a binary representation::
>>> usocket.inet_pton(usocket.AF_INET, "1.2.3.4")
b'\x01\x02\x03\x04'
Constants
---------
.. data:: AF_INET
AF_INET6
Address family types. Availability depends on a particular ``MicroPython port``.
.. data:: SOCK_STREAM
SOCK_DGRAM
Socket types.
.. data:: IPPROTO_UDP
IPPROTO_TCP
IP protocol numbers. Availability depends on a particular ``MicroPython port``.
Note that you don't need to specify these in a call to `usocket.socket()`,
because `SOCK_STREAM` socket type automatically selects `IPPROTO_TCP`, and
`SOCK_DGRAM` - `IPPROTO_UDP`. Thus, the only real use of these constants
is as an argument to `usocket.socket.setsockopt()`.
.. data:: usocket.SOL_*
Socket option levels (an argument to `usocket.socket.setsockopt()`). The exact
inventory depends on a ``MicroPython port``.
.. data:: usocket.SO_*
Socket options (an argument to `usocket.socket.setsockopt()`). The exact
inventory depends on a ``MicroPython port``.
Constants specific to WiPy:
.. data:: IPPROTO_SEC
Special protocol value to create SSL-compatible socket.
class socket
============
Methods
-------
.. method:: socket.close()
Mark the socket closed and release all resources. Once that happens, all future operations
on the socket object will fail. The remote end will receive EOF indication if
supported by protocol.
Sockets are automatically closed when they are garbage-collected, but it is recommended
to `close()` them explicitly as soon you finished working with them.
.. method:: socket.bind(address)
Bind the socket to *address*. The socket must not already be bound.
.. method:: socket.listen([backlog])
Enable a server to accept connections. If *backlog* is specified, it must be at least 0
(if it's lower, it will be set to 0); and specifies the number of unaccepted connections
that the system will allow before refusing new connections. If not specified, a default
reasonable value is chosen.
.. method:: socket.accept()
Accept a connection. The socket must be bound to an address and listening for connections.
The return value is a pair (conn, address) where conn is a new socket object usable to send
and receive data on the connection, and address is the address bound to the socket on the
other end of the connection.
.. method:: socket.connect(address)
Connect to a remote socket at *address*.
.. method:: socket.send(bytes)
Send data to the socket. The socket must be connected to a remote socket.
Returns number of bytes sent, which may be smaller than the length of data
("short write").
.. method:: socket.sendall(bytes)
Send all data to the socket. The socket must be connected to a remote socket.
Unlike `send()`, this method will try to send all of data, by sending data
chunk by chunk consecutively.
The behavior of this method on non-blocking sockets is undefined. Due to this,
on MicroPython, it's recommended to use `write()` method instead, which
has the same "no short writes" policy for blocking sockets, and will return
number of bytes sent on non-blocking sockets.
.. method:: socket.recv(bufsize)
Receive data from the socket. The return value is a bytes object representing the data
received. The maximum amount of data to be received at once is specified by bufsize.
.. method:: socket.sendto(bytes, address)
Send data to the socket. The socket should not be connected to a remote socket, since the
destination socket is specified by *address*.
.. method:: socket.recvfrom(bufsize)
Receive data from the socket. The return value is a pair *(bytes, address)* where *bytes* is a
bytes object representing the data received and *address* is the address of the socket sending
the data.
.. method:: socket.setsockopt(level, optname, value)
Set the value of the given socket option. The needed symbolic constants are defined in the
socket module (SO_* etc.). The *value* can be an integer or a bytes-like object representing
a buffer.
.. method:: socket.settimeout(value)
**Note**: Not every port supports this method, see below.
Set a timeout on blocking socket operations. The value argument can be a nonnegative floating
point number expressing seconds, or None. If a non-zero value is given, subsequent socket operations
will raise an `OSError` exception if the timeout period value has elapsed before the operation has
completed. If zero is given, the socket is put in non-blocking mode. If None is given, the socket
is put in blocking mode.
Not every ``MicroPython port`` supports this method. A more portable and
generic solution is to use `uselect.poll` object. This allows to wait on
multiple objects at the same time (and not just on sockets, but on generic
``stream`` objects which support polling). Example::
# Instead of:
s.settimeout(1.0) # time in seconds
s.read(10) # may timeout
# Use:
poller = uselect.poll()
poller.register(s, uselect.POLLIN)
res = poller.poll(1000) # time in milliseconds
if not res:
# s is still not ready for input, i.e. operation timed out
.. admonition:: Difference to CPython
:class: attention
CPython raises a ``socket.timeout`` exception in case of timeout,
which is an `OSError` subclass. MicroPython raises an OSError directly
instead. If you use ``except OSError:`` to catch the exception,
your code will work both in MicroPython and CPython.
.. method:: socket.setblocking(flag)
Set blocking or non-blocking mode of the socket: if flag is false, the socket is set to non-blocking,
else to blocking mode.
This method is a shorthand for certain `settimeout()` calls:
* ``sock.setblocking(True)`` is equivalent to ``sock.settimeout(None)``
* ``sock.setblocking(False)`` is equivalent to ``sock.settimeout(0)``
.. method:: socket.makefile(mode='rb', buffering=0)
Return a file object associated with the socket. The exact returned type depends on the arguments
given to makefile(). The support is limited to binary modes only ('rb', 'wb', and 'rwb').
CPython's arguments: *encoding*, *errors* and *newline* are not supported.
.. admonition:: Difference to CPython
:class: attention
As MicroPython doesn't support buffered streams, values of *buffering*
parameter is ignored and treated as if it was 0 (unbuffered).
.. admonition:: Difference to CPython
:class: attention
Closing the file object returned by makefile() WILL close the
original socket as well.
.. method:: socket.read([size])
Read up to size bytes from the socket. Return a bytes object. If *size* is not given, it
reads all data available from the socket until EOF; as such the method will not return until
the socket is closed. This function tries to read as much data as
requested (no "short reads"). This may be not possible with
non-blocking socket though, and then less data will be returned.
.. method:: socket.readinto(buf[, nbytes])
Read bytes into the *buf*. If *nbytes* is specified then read at most
that many bytes. Otherwise, read at most *len(buf)* bytes. Just as
`read()`, this method follows "no short reads" policy.
Return value: number of bytes read and stored into *buf*.
.. method:: socket.readline()
Read a line, ending in a newline character.
Return value: the line read.
.. method:: socket.write(buf)
Write the buffer of bytes to the socket. This function will try to
write all data to a socket (no "short writes"). This may be not possible
with a non-blocking socket though, and returned value will be less than
the length of *buf*.
Return value: number of bytes written.
.. exception:: usocket.error
MicroPython does NOT have this exception.
.. admonition:: Difference to CPython
:class: attention
CPython used to have a ``socket.error`` exception which is now deprecated,
and is an alias of `OSError`. In MicroPython, use `OSError` directly.

View file

@ -1,50 +0,0 @@
:mod:`ussl` -- SSL/TLS module
=============================
.. include:: ../templates/unsupported_in_circuitpython.inc
.. module:: ussl
:synopsis: TLS/SSL wrapper for socket objects
|see_cpython_module| :mod:`cpython:ssl`.
This module provides access to Transport Layer Security (previously and
widely known as “Secure Sockets Layer”) encryption and peer authentication
facilities for network sockets, both client-side and server-side.
Functions
---------
.. function:: ussl.wrap_socket(sock, server_side=False, keyfile=None, certfile=None, cert_reqs=CERT_NONE, ca_certs=None)
Takes a ``stream`` *sock* (usually usocket.socket instance of ``SOCK_STREAM`` type),
and returns an instance of ssl.SSLSocket, which wraps the underlying stream in
an SSL context. Returned object has the usual ``stream`` interface methods like
``read()``, ``write()``, etc. In MicroPython, the returned object does not expose
socket interface and methods like ``recv()``, ``send()``. In particular, a
server-side SSL socket should be created from a normal socket returned from
:meth:`~usocket.socket.accept()` on a non-SSL listening server socket.
Depending on the underlying module implementation in a particular
``MicroPython port``, some or all keyword arguments above may be not supported.
.. warning::
Some implementations of ``ussl`` module do NOT validate server certificates,
which makes an SSL connection established prone to man-in-the-middle attacks.
Exceptions
----------
.. data:: ssl.SSLError
This exception does NOT exist. Instead its base class, OSError, is used.
Constants
---------
.. data:: ussl.CERT_NONE
ussl.CERT_OPTIONAL
ussl.CERT_REQUIRED
Supported values for *cert_reqs* parameter.

View file

@ -1,6 +0,0 @@
User-agent: *
Allow: /*/latest/
Allow: /en/latest/ # Fallback for bots that don't understand wildcards
Allow: /*/6.0.x/
Allow: /en/6.0.x/ # Fallback for bots that don't understand wildcards
Disallow: /

View file

@ -32,6 +32,39 @@ from concurrent.futures import ThreadPoolExecutor
SUPPORTED_PORTS = ['atmel-samd', 'cxd56', 'esp32s2', 'litex', 'mimxrt10xx', 'nrf', 'raspberrypi', 'stm'] SUPPORTED_PORTS = ['atmel-samd', 'cxd56', 'esp32s2', 'litex', 'mimxrt10xx', 'nrf', 'raspberrypi', 'stm']
aliases_by_board = {
"circuitplayground_express": [
"circuitplayground_express_4h",
"circuitplayground_express_digikey_pycon2019",
],
"pybadge": ["edgebadge"],
"pyportal": ["pyportal_pynt"],
"gemma_m0": ["gemma_m0_pycon2018"],
"pewpew10": ["pewpew13"],
}
aliases_brand_names = {
"circuitplayground_express_4h":
"Adafruit Circuit Playground Express 4-H",
"circuitplayground_express_digikey_pycon2019":
"Circuit Playground Express Digi-Key PyCon 2019",
"edgebadge":
"Adafruit EdgeBadge",
"pyportal_pynt":
"Adafruit PyPortal Pynt",
"gemma_m0_pycon2018":
"Adafruit Gemma M0 PyCon 2018",
"pewpew13":
"PewPew 13",
}
additional_modules = {
"fontio": "CIRCUITPY_DISPLAYIO",
"terminalio": "CIRCUITPY_DISPLAYIO",
# "socket": "CIRCUITPY_NETWORK",
"adafruit_bus_device": "CIRCUITPY_BUSDEVICE",
}
def get_circuitpython_root_dir(): def get_circuitpython_root_dir():
""" The path to the root './circuitpython' directory """ The path to the root './circuitpython' directory
""" """
@ -71,8 +104,11 @@ def build_module_map():
full_build = False full_build = False
for module in modules: for module in modules:
full_name = module full_name = module
search_name = module.lstrip("_") if module in additional_modules:
re_pattern = "CIRCUITPY_{}\s*\??=\s*(.+)".format(search_name.upper()) search_identifier = additional_modules[module]
else:
search_identifier = 'CIRCUITPY_'+module.lstrip("_").upper()
re_pattern = f"{re.escape(search_identifier)}\s*\??=\s*(.+)"
find_config = re.findall(re_pattern, configs) find_config = re.findall(re_pattern, configs)
if not find_config: if not find_config:
continue continue
@ -84,11 +120,12 @@ def build_module_map():
else: else:
default_val = "None" default_val = "None"
base[search_name] = { base[module] = {
"name": full_name, "name": full_name,
"full_build": str(full_build), "full_build": str(full_build),
"default_value": default_val, "default_value": default_val,
"excluded": {} "excluded": {},
"key": search_identifier,
} }
return base return base
@ -164,14 +201,28 @@ def support_matrix_by_board(use_branded_name=True):
board_modules = [] board_modules = []
for module in base: for module in base:
key = f'CIRCUITPY_{module.upper()}' key = base[module]['key']
if int(lookup_setting(settings, key, '0')): if int(lookup_setting(settings, key, '0')):
board_modules.append(base[module]['name']) board_modules.append(base[module]['name'])
board_modules.sort()
return (board_name, sorted(board_modules)) # generate alias boards too
board_matrix = [(board_name, board_modules)]
if entry.name in aliases_by_board:
for alias in aliases_by_board[entry.name]:
if use_branded_name:
if alias in aliases_brand_names:
alias = aliases_brand_names[alias]
else:
alias = alias.replace("_"," ").title()
board_matrix.append( (alias, 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())
boards = dict(sorted(executor.map(support_matrix, all_ports_all_boards()))) mapped_exec = executor.map(support_matrix, all_ports_all_boards())
# flatmap with comprehensions
boards = dict(sorted([board for matrix in mapped_exec for board in matrix]))
#print(json.dumps(boards, indent=2)) #print(json.dumps(boards, indent=2))
return boards return boards

17
docs/static/filter.css vendored Normal file
View file

@ -0,0 +1,17 @@
#support-matrix-filter-block { position: relative; }
#support-matrix-filter {
width: 100%;
}
#support-matrix-filter-num {
position: absolute;
right: 10px;
top: 4px;
}
.support-matrix-table .this_module code,
.support-matrix-table .this_module span {
background: black;
color: white;
}
.support-matrix-table .board_hidden {
display: none;
}

86
docs/static/filter.js vendored Normal file
View file

@ -0,0 +1,86 @@
$(() => {
var urlTimeout = null;
function setURL(query, value) {
clearTimeout(urlTimeout);
urlTimeout = setTimeout(function() {
var url = new URL(window.location.href);
console.log(query,value,value.length,!value.length);
if (!value.length) {
console.log
url.searchParams.delete(query);
} else if (Array.isArray(value)) {
url.searchParams.delete(query);
value.forEach(function(v) {
url.searchParams.append(query, v);
})
} else {
url.searchParams.set(query, value);
}
window.history.pushState(null, document.title, url.href);
}, 1000);
}
function handlePageLoad() {
var url = new URL(window.location.href);
//get values from URL
var filters = url.searchParams.getAll('filter');
search_terms = filters.join(" ");
$("#support-matrix-filter").val(search_terms);
run_filter();
}
function filter_boards(search_string) {
$(".board_hidden").removeClass("board_hidden");
$(".this_module").removeClass("this_module");
var nboards = $(".support-matrix-table tbody tr").length;
if(search_string.trim() == "") {
$("#support-matrix-filter-num").html("(all)");
setURL("filter",[]);
return;
}
var list_search = search_string.split(" ").filter(i => i);
var nvisible = 0;
$(".support-matrix-table tbody tr").each( (index,item) => {
var name = $(item).find("td:first-child p").html();
var modules = $(item).find("a.reference.internal");
var matching_all = true;
//
list_search.forEach((sstring) => {
var matching = (sstring[0] == "-");
for(var modi = 0; modi < modules.length; ++modi) {
module = modules[modi];
var mod_name = module.firstChild.firstChild.textContent;
if(sstring[0] == "-") {
if(mod_name.match(sstring.substr(1))) {
matching = false;
break;
}
} else {
if(mod_name.match(sstring)) {
$(module).addClass("this_module");
matching = true;
}
}
}
matching_all = matching_all && matching;
});
if(!matching_all) {
$(item).addClass("board_hidden");
} else {
nvisible += 1;
}
});
$("#support-matrix-filter-num").html(`(${nvisible}/${nboards})`);
setURL("filter",list_search);
}
function run_filter() {
var search_string = $("#support-matrix-filter").val();
filter_boards(search_string);
}
$("#support-matrix-filter").on("keyup", run_filter);
// $(document).on("keyup", "#support-matrix-filter", run_filter);
handlePageLoad();
});

View file

@ -1,203 +0,0 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* SPDX-FileCopyrightText: Copyright (c) 2017-2018 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.
*/
#include "drivers/bus/qspi.h"
#define CS_LOW(self) mp_hal_pin_write(self->cs, 0)
#define CS_HIGH(self) mp_hal_pin_write(self->cs, 1)
#ifdef MICROPY_HW_SOFTQSPI_SCK_LOW
// Use externally provided functions for SCK control and IO reading
#define SCK_LOW(self) MICROPY_HW_SOFTQSPI_SCK_LOW(self)
#define SCK_HIGH(self) MICROPY_HW_SOFTQSPI_SCK_HIGH(self)
#define NIBBLE_READ(self) MICROPY_HW_SOFTQSPI_NIBBLE_READ(self)
#else
// Use generic pin functions for SCK control and IO reading
#define SCK_LOW(self) mp_hal_pin_write(self->clk, 0)
#define SCK_HIGH(self) mp_hal_pin_write(self->clk, 1)
#define NIBBLE_READ(self) ( \
mp_hal_pin_read(self->io0) \
| (mp_hal_pin_read(self->io1) << 1) \
| (mp_hal_pin_read(self->io2) << 2) \
| (mp_hal_pin_read(self->io3) << 3))
#endif
STATIC void nibble_write(mp_soft_qspi_obj_t *self, uint8_t v) {
mp_hal_pin_write(self->io0, v & 1);
mp_hal_pin_write(self->io1, (v >> 1) & 1);
mp_hal_pin_write(self->io2, (v >> 2) & 1);
mp_hal_pin_write(self->io3, (v >> 3) & 1);
}
STATIC int mp_soft_qspi_ioctl(void *self_in, uint32_t cmd) {
mp_soft_qspi_obj_t *self = (mp_soft_qspi_obj_t*)self_in;
switch (cmd) {
case MP_QSPI_IOCTL_INIT:
mp_hal_pin_high(self->cs);
mp_hal_pin_output(self->cs);
// Configure pins
mp_hal_pin_write(self->clk, 0);
mp_hal_pin_output(self->clk);
//mp_hal_pin_write(self->clk, 1);
mp_hal_pin_output(self->io0);
mp_hal_pin_input(self->io1);
mp_hal_pin_write(self->io2, 1);
mp_hal_pin_output(self->io2);
mp_hal_pin_write(self->io3, 1);
mp_hal_pin_output(self->io3);
break;
}
return 0; // success
}
STATIC void mp_soft_qspi_transfer(mp_soft_qspi_obj_t *self, size_t len, const uint8_t *src, uint8_t *dest) {
// Will run as fast as possible, limited only by CPU speed and GPIO time
mp_hal_pin_input(self->io1);
mp_hal_pin_output(self->io0);
if (self->io3) {
mp_hal_pin_write(self->io2, 1);
mp_hal_pin_output(self->io2);
mp_hal_pin_write(self->io3, 1);
mp_hal_pin_output(self->io3);
}
if (src) {
for (size_t i = 0; i < len; ++i) {
uint8_t data_out = src[i];
uint8_t data_in = 0;
for (int j = 0; j < 8; ++j, data_out <<= 1) {
mp_hal_pin_write(self->io0, (data_out >> 7) & 1);
mp_hal_pin_write(self->clk, 1);
data_in = (data_in << 1) | mp_hal_pin_read(self->io1);
mp_hal_pin_write(self->clk, 0);
}
if (dest != NULL) {
dest[i] = data_in;
}
}
} else {
for (size_t i = 0; i < len; ++i) {
uint8_t data_in = 0;
for (int j = 0; j < 8; ++j) {
mp_hal_pin_write(self->clk, 1);
data_in = (data_in << 1) | mp_hal_pin_read(self->io1);
mp_hal_pin_write(self->clk, 0);
}
if (dest != NULL) {
dest[i] = data_in;
}
}
}
}
STATIC void mp_soft_qspi_qread(mp_soft_qspi_obj_t *self, size_t len, uint8_t *buf) {
// Make all IO lines input
mp_hal_pin_input(self->io2);
mp_hal_pin_input(self->io3);
mp_hal_pin_input(self->io0);
mp_hal_pin_input(self->io1);
// Will run as fast as possible, limited only by CPU speed and GPIO time
while (len--) {
SCK_HIGH(self);
uint8_t data_in = NIBBLE_READ(self);
SCK_LOW(self);
SCK_HIGH(self);
*buf++ = (data_in << 4) | NIBBLE_READ(self);
SCK_LOW(self);
}
}
STATIC void mp_soft_qspi_qwrite(mp_soft_qspi_obj_t *self, size_t len, const uint8_t *buf) {
// Make all IO lines output
mp_hal_pin_output(self->io2);
mp_hal_pin_output(self->io3);
mp_hal_pin_output(self->io0);
mp_hal_pin_output(self->io1);
// Will run as fast as possible, limited only by CPU speed and GPIO time
for (size_t i = 0; i < len; ++i) {
nibble_write(self, buf[i] >> 4);
SCK_HIGH(self);
SCK_LOW(self);
nibble_write(self, buf[i]);
SCK_HIGH(self);
SCK_LOW(self);
}
//mp_hal_pin_input(self->io1);
}
STATIC void mp_soft_qspi_write_cmd_data(void *self_in, uint8_t cmd, size_t len, uint32_t data) {
mp_soft_qspi_obj_t *self = (mp_soft_qspi_obj_t*)self_in;
uint32_t cmd_buf = cmd | data << 8;
CS_LOW(self);
mp_soft_qspi_transfer(self, 1 + len, (uint8_t*)&cmd_buf, NULL);
CS_HIGH(self);
}
STATIC void mp_soft_qspi_write_cmd_addr_data(void *self_in, uint8_t cmd, uint32_t addr, size_t len, const uint8_t *src) {
mp_soft_qspi_obj_t *self = (mp_soft_qspi_obj_t*)self_in;
uint8_t cmd_buf[4] = {cmd, addr >> 16, addr >> 8, addr};
CS_LOW(self);
mp_soft_qspi_transfer(self, 4, cmd_buf, NULL);
mp_soft_qspi_transfer(self, len, src, NULL);
CS_HIGH(self);
}
STATIC uint32_t mp_soft_qspi_read_cmd(void *self_in, uint8_t cmd, size_t len) {
mp_soft_qspi_obj_t *self = (mp_soft_qspi_obj_t*)self_in;
uint32_t cmd_buf = cmd;
CS_LOW(self);
mp_soft_qspi_transfer(self, 1 + len, (uint8_t*)&cmd_buf, (uint8_t*)&cmd_buf);
CS_HIGH(self);
return cmd_buf >> 8;
}
STATIC void mp_soft_qspi_read_cmd_qaddr_qdata(void *self_in, uint8_t cmd, uint32_t addr, size_t len, uint8_t *dest) {
mp_soft_qspi_obj_t *self = (mp_soft_qspi_obj_t*)self_in;
uint8_t cmd_buf[7] = {cmd, addr >> 16, addr >> 8, addr};
CS_LOW(self);
mp_soft_qspi_transfer(self, 1, cmd_buf, NULL);
mp_soft_qspi_qwrite(self, 6, &cmd_buf[1]); // 3 addr bytes, 1 extra byte (0), 2 dummy bytes (4 dummy cycles)
mp_soft_qspi_qread(self, len, dest);
CS_HIGH(self);
}
const mp_qspi_proto_t mp_soft_qspi_proto = {
.ioctl = mp_soft_qspi_ioctl,
.write_cmd_data = mp_soft_qspi_write_cmd_data,
.write_cmd_addr_data = mp_soft_qspi_write_cmd_addr_data,
.read_cmd = mp_soft_qspi_read_cmd,
.read_cmd_qaddr_qdata = mp_soft_qspi_read_cmd_qaddr_qdata,
};

View file

@ -1,105 +0,0 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* SPDX-FileCopyrightText: Copyright (c) 2016-2018 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.
*/
#include "drivers/bus/spi.h"
int mp_soft_spi_ioctl(void *self_in, uint32_t cmd) {
mp_soft_spi_obj_t *self = (mp_soft_spi_obj_t*)self_in;
switch (cmd) {
case MP_SPI_IOCTL_INIT:
mp_hal_pin_write(self->sck, self->polarity);
mp_hal_pin_output(self->sck);
mp_hal_pin_output(self->mosi);
mp_hal_pin_input(self->miso);
break;
case MP_SPI_IOCTL_DEINIT:
break;
}
return 0;
}
void mp_soft_spi_transfer(void *self_in, size_t len, const uint8_t *src, uint8_t *dest) {
mp_soft_spi_obj_t *self = (mp_soft_spi_obj_t*)self_in;
uint32_t delay_half = self->delay_half;
// only MSB transfer is implemented
// If a port defines MICROPY_HW_SOFTSPI_MIN_DELAY, and the configured
// delay_half is equal to this value, then the software SPI implementation
// will run as fast as possible, limited only by CPU speed and GPIO time.
#ifdef MICROPY_HW_SOFTSPI_MIN_DELAY
if (delay_half == MICROPY_HW_SOFTSPI_MIN_DELAY) {
for (size_t i = 0; i < len; ++i) {
uint8_t data_out = src[i];
uint8_t data_in = 0;
for (int j = 0; j < 8; ++j, data_out <<= 1) {
mp_hal_pin_write(self->mosi, (data_out >> 7) & 1);
mp_hal_pin_write(self->sck, 1 - self->polarity);
data_in = (data_in << 1) | mp_hal_pin_read(self->miso);
mp_hal_pin_write(self->sck, self->polarity);
}
if (dest != NULL) {
dest[i] = data_in;
}
}
return;
}
#endif
for (size_t i = 0; i < len; ++i) {
uint8_t data_out = src[i];
uint8_t data_in = 0;
for (int j = 0; j < 8; ++j, data_out <<= 1) {
mp_hal_pin_write(self->mosi, (data_out >> 7) & 1);
if (self->phase == 0) {
mp_hal_delay_us_fast(delay_half);
mp_hal_pin_write(self->sck, 1 - self->polarity);
} else {
mp_hal_pin_write(self->sck, 1 - self->polarity);
mp_hal_delay_us_fast(delay_half);
}
data_in = (data_in << 1) | mp_hal_pin_read(self->miso);
if (self->phase == 0) {
mp_hal_delay_us_fast(delay_half);
mp_hal_pin_write(self->sck, self->polarity);
} else {
mp_hal_pin_write(self->sck, self->polarity);
mp_hal_delay_us_fast(delay_half);
}
}
if (dest != NULL) {
dest[i] = data_in;
}
}
}
const mp_spi_proto_t mp_soft_spi_proto = {
.ioctl = mp_soft_spi_ioctl,
.transfer = mp_soft_spi_transfer,
};

View file

@ -1,6 +0,0 @@
This is the driver for the WIZnet5x00 series of Ethernet controllers.
Adapted for MicroPython.
Original source: https://github.com/Wiznet/W5500_EVB/tree/master/ioLibrary
Taken on: 30 August 2014

View file

@ -1,718 +0,0 @@
//*****************************************************************************
//
//! \file socket.c
//! \brief SOCKET APIs Implements file.
//! \details SOCKET APIs like as Berkeley Socket APIs.
//! \version 1.0.3
//! \date 2013/10/21
//! \par Revision history
//! <2018/10/09> Nick Moore fixes for CircuitPython
//! <2014/05/01> V1.0.3. Refer to M20140501
//! 1. Implicit type casting -> Explicit type casting.
//! 2. replace 0x01 with PACK_REMAINED in recvfrom()
//! 3. Validation a destination ip in connect() & sendto():
//! It occurs a fatal error on converting unint32 address if uint8* addr parameter is not aligned by 4byte address.
//! Copy 4 byte addr value into temporary uint32 variable and then compares it.
//! <2013/12/20> V1.0.2 Refer to M20131220
//! Remove Warning.
//! <2013/11/04> V1.0.1 2nd Release. Refer to "20131104".
//! In sendto(), Add to clear timeout interrupt status (Sn_IR_TIMEOUT)
//! <2013/10/21> 1st Release
//! \author MidnightCow
//! \copyright
//!
//! Copyright (c) 2013, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
#include <string.h>
#include "py/mpthread.h"
#include "socket.h"
#define SOCK_ANY_PORT_NUM 0xC000;
static uint16_t sock_any_port = SOCK_ANY_PORT_NUM;
static uint16_t sock_io_mode = 0;
static uint16_t sock_is_sending = 0;
static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0,0,};
static uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,};
#if _WIZCHIP_ == 5200
static uint16_t sock_next_rd[_WIZCHIP_SOCK_NUM_] ={0,};
#endif
#define CHECK_SOCKNUM() \
do{ \
if(sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM; \
}while(0); \
#define CHECK_SOCKMODE(mode) \
do{ \
if((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; \
}while(0); \
#define CHECK_SOCKINIT() \
do{ \
if((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \
}while(0); \
#define CHECK_SOCKDATA() \
do{ \
if(len == 0) return SOCKERR_DATALEN; \
}while(0); \
void WIZCHIP_EXPORT(socket_reset)(void) {
sock_any_port = SOCK_ANY_PORT_NUM;
sock_io_mode = 0;
sock_is_sending = 0;
/*
memset(sock_remained_size, 0, _WIZCHIP_SOCK_NUM_ * sizeof(uint16_t));
memset(sock_pack_info, 0, _WIZCHIP_SOCK_NUM_ * sizeof(uint8_t));
*/
#if _WIZCHIP_ == 5200
memset(sock_next_rd, 0, _WIZCHIP_SOCK_NUM_ * sizeof(uint16_t));
#endif
}
int8_t WIZCHIP_EXPORT(socket)(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag)
{
CHECK_SOCKNUM();
switch(protocol)
{
case Sn_MR_TCP :
case Sn_MR_UDP :
case Sn_MR_MACRAW :
break;
#if ( _WIZCHIP_ < 5200 )
case Sn_MR_IPRAW :
case Sn_MR_PPPoE :
break;
#endif
default :
return SOCKERR_SOCKMODE;
}
if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG;
#if _WIZCHIP_ == 5200
if(flag & 0x10) return SOCKERR_SOCKFLAG;
#endif
if(flag != 0)
{
switch(protocol)
{
case Sn_MR_TCP:
if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK))==0) return SOCKERR_SOCKFLAG;
break;
case Sn_MR_UDP:
if(flag & SF_IGMP_VER2)
{
if((flag & SF_MULTI_ENABLE)==0) return SOCKERR_SOCKFLAG;
}
#if _WIZCHIP_ == 5500
if(flag & SF_UNI_BLOCK)
{
if((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG;
}
#endif
break;
default:
break;
}
}
WIZCHIP_EXPORT(close)(sn);
setSn_MR(sn, (protocol | (flag & 0xF0)));
if(!port)
{
port = sock_any_port++;
if(sock_any_port == 0xFFF0) sock_any_port = SOCK_ANY_PORT_NUM;
}
setSn_PORT(sn,port);
setSn_CR(sn,Sn_CR_OPEN);
while(getSn_CR(sn));
sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn);
sock_is_sending &= ~(1<<sn);
sock_remained_size[sn] = 0;
sock_pack_info[sn] = 0;
while(getSn_SR(sn) == SOCK_CLOSED);
return (int8_t)sn;
}
int8_t WIZCHIP_EXPORT(close)(uint8_t sn)
{
CHECK_SOCKNUM();
setSn_CR(sn,Sn_CR_CLOSE);
/* wait to process the command... */
while( getSn_CR(sn) );
/* clear all interrupt of the socket. */
setSn_IR(sn, 0xFF);
sock_is_sending &= ~(1<<sn);
sock_remained_size[sn] = 0;
sock_pack_info[sn] = 0;
while(getSn_SR(sn) != SOCK_CLOSED);
return SOCK_OK;
}
int8_t WIZCHIP_EXPORT(listen)(uint8_t sn)
{
CHECK_SOCKNUM();
CHECK_SOCKMODE(Sn_MR_TCP);
CHECK_SOCKINIT();
setSn_CR(sn,Sn_CR_LISTEN);
while(getSn_CR(sn));
while(getSn_SR(sn) != SOCK_LISTEN)
{
if(getSn_CR(sn) == SOCK_CLOSED)
{
WIZCHIP_EXPORT(close)(sn);
return SOCKERR_SOCKCLOSED;
}
}
return SOCK_OK;
}
int8_t WIZCHIP_EXPORT(connect)(uint8_t sn, uint8_t * addr, uint16_t port)
{
CHECK_SOCKNUM();
CHECK_SOCKMODE(Sn_MR_TCP);
CHECK_SOCKINIT();
//M20140501 : For avoiding fatal error on memory align mismatched
//if( *((uint32_t*)addr) == 0xFFFFFFFF || *((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
{
uint32_t taddr;
taddr = ((uint32_t)addr[0] & 0x000000FF);
taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF);
taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF);
taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF);
if (taddr == 0xFFFFFFFF || taddr == 0) return SOCKERR_IPINVALID;
}
//
if(port == 0) return SOCKERR_PORTZERO;
setSn_DIPR(sn,addr);
setSn_DPORT(sn,port);
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
setSUBR(wizchip_getsubn());
#endif
setSn_CR(sn,Sn_CR_CONNECT);
while(getSn_CR(sn));
if(sock_io_mode & (1<<sn)) return SOCK_BUSY;
while(getSn_SR(sn) != SOCK_ESTABLISHED)
{
if (getSn_SR(sn) == SOCK_CLOSED) {
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
setSUBR((uint8_t*)"\x00\x00\x00\x00");
#endif
return SOCKERR_SOCKCLOSED;
}
if (getSn_IR(sn) & Sn_IR_TIMEOUT)
{
setSn_IR(sn, Sn_IR_TIMEOUT);
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
setSUBR((uint8_t*)"\x00\x00\x00\x00");
#endif
return SOCKERR_TIMEOUT;
}
MICROPY_THREAD_YIELD();
}
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
setSUBR((uint8_t*)"\x00\x00\x00\x00");
#endif
return SOCK_OK;
}
int8_t WIZCHIP_EXPORT(disconnect)(uint8_t sn)
{
CHECK_SOCKNUM();
CHECK_SOCKMODE(Sn_MR_TCP);
setSn_CR(sn,Sn_CR_DISCON);
/* wait to process the command... */
while(getSn_CR(sn));
sock_is_sending &= ~(1<<sn);
if(sock_io_mode & (1<<sn)) return SOCK_BUSY;
while(getSn_SR(sn) != SOCK_CLOSED)
{
if(getSn_IR(sn) & Sn_IR_TIMEOUT)
{
WIZCHIP_EXPORT(close)(sn);
return SOCKERR_TIMEOUT;
}
}
return SOCK_OK;
}
int32_t WIZCHIP_EXPORT(send)(uint8_t sn, uint8_t * buf, uint16_t len)
{
uint8_t tmp=0;
uint16_t freesize=0;
CHECK_SOCKNUM();
CHECK_SOCKMODE(Sn_MR_TCP);
CHECK_SOCKDATA();
tmp = getSn_SR(sn);
if(tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) return SOCKERR_SOCKSTATUS;
if( sock_is_sending & (1<<sn) )
{
tmp = getSn_IR(sn);
if(tmp & Sn_IR_SENDOK)
{
setSn_IR(sn, Sn_IR_SENDOK);
#if _WIZCHIP_ == 5200
if(getSn_TX_RD(sn) != sock_next_rd[sn])
{
setSn_CR(sn,Sn_CR_SEND);
while(getSn_CR(sn));
return SOCKERR_BUSY;
}
#endif
sock_is_sending &= ~(1<<sn);
}
else if(tmp & Sn_IR_TIMEOUT)
{
WIZCHIP_EXPORT(close)(sn);
return SOCKERR_TIMEOUT;
}
else return SOCK_BUSY;
}
freesize = getSn_TxMAX(sn);
if (len > freesize) len = freesize; // check size not to exceed MAX size.
while(1)
{
freesize = getSn_TX_FSR(sn);
tmp = getSn_SR(sn);
if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT))
{
WIZCHIP_EXPORT(close)(sn);
return SOCKERR_SOCKSTATUS;
}
if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
if(len <= freesize) break;
MICROPY_THREAD_YIELD();
}
wiz_send_data(sn, buf, len);
#if _WIZCHIP_ == 5200
sock_next_rd[sn] = getSn_TX_RD(sn) + len;
#endif
setSn_CR(sn,Sn_CR_SEND);
/* wait to process the command... */
while(getSn_CR(sn));
sock_is_sending |= (1 << sn);
return len;
}
int32_t WIZCHIP_EXPORT(recv)(uint8_t sn, uint8_t * buf, uint16_t len)
{
uint8_t tmp = 0;
uint16_t recvsize = 0;
CHECK_SOCKNUM();
CHECK_SOCKMODE(Sn_MR_TCP);
CHECK_SOCKDATA();
recvsize = getSn_RxMAX(sn);
if(recvsize < len) len = recvsize;
while(1)
{
recvsize = getSn_RX_RSR(sn);
tmp = getSn_SR(sn);
if (tmp != SOCK_ESTABLISHED)
{
if(tmp == SOCK_CLOSE_WAIT)
{
if(recvsize != 0) break;
else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn))
{
// dpgeorge: Getting here seems to be an orderly shutdown of the
// socket, and trying to get POSIX behaviour we return 0 because:
// "If no messages are available to be received and the peer has per
// formed an orderly shutdown, recv() shall return 0".
// TODO this return value clashes with SOCK_BUSY in non-blocking mode.
WIZCHIP_EXPORT(close)(sn);
return 0;
}
}
else
{
WIZCHIP_EXPORT(close)(sn);
return SOCKERR_SOCKSTATUS;
}
}
if((sock_io_mode & (1<<sn)) && (recvsize == 0)) return SOCK_BUSY;
if(recvsize != 0) break;
MICROPY_THREAD_YIELD();
};
if(recvsize < len) len = recvsize;
wiz_recv_data(sn, buf, len);
setSn_CR(sn,Sn_CR_RECV);
while(getSn_CR(sn));
return len;
}
int32_t WIZCHIP_EXPORT(sendto)(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port)
{
uint8_t tmp = 0;
uint16_t freesize = 0;
CHECK_SOCKNUM();
switch(getSn_MR(sn) & 0x0F)
{
case Sn_MR_UDP:
case Sn_MR_MACRAW:
break;
default:
return SOCKERR_SOCKMODE;
}
CHECK_SOCKDATA();
//M20140501 : For avoiding fatal error on memory align mismatched
//if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
if ((addr[0] | addr[1] | addr[2] | addr[3]) == 0) return SOCKERR_IPINVALID;
if(port == 0) return SOCKERR_PORTZERO;
tmp = getSn_SR(sn);
if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS;
setSn_DIPR(sn,addr);
setSn_DPORT(sn,port);
freesize = getSn_TxMAX(sn);
if (len > freesize) len = freesize; // check size not to exceed MAX size.
while(1)
{
freesize = getSn_TX_FSR(sn);
if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED;
if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
if(len <= freesize) break;
MICROPY_THREAD_YIELD();
};
wiz_send_data(sn, buf, len);
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
setSUBR(wizchip_getsubn());
#endif
setSn_CR(sn,Sn_CR_SEND);
/* wait to process the command... */
while(getSn_CR(sn));
while(1)
{
tmp = getSn_IR(sn);
if(tmp & Sn_IR_SENDOK)
{
setSn_IR(sn, Sn_IR_SENDOK);
break;
}
//M:20131104
//else if(tmp & Sn_IR_TIMEOUT) return SOCKERR_TIMEOUT;
else if(tmp & Sn_IR_TIMEOUT)
{
setSn_IR(sn, Sn_IR_TIMEOUT);
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
setSUBR((uint8_t*)"\x00\x00\x00\x00");
#endif
return SOCKERR_TIMEOUT;
}
////////////
MICROPY_THREAD_YIELD();
}
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
setSUBR((uint8_t*)"\x00\x00\x00\x00");
#endif
return len;
}
int32_t WIZCHIP_EXPORT(recvfrom)(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port)
{
uint8_t mr;
uint8_t head[8];
uint16_t pack_len=0;
CHECK_SOCKNUM();
//CHECK_SOCKMODE(Sn_MR_UDP);
switch((mr=getSn_MR(sn)) & 0x0F)
{
case Sn_MR_UDP:
case Sn_MR_MACRAW:
break;
#if ( _WIZCHIP_ < 5200 )
case Sn_MR_IPRAW:
case Sn_MR_PPPoE:
break;
#endif
default:
return SOCKERR_SOCKMODE;
}
CHECK_SOCKDATA();
if(sock_remained_size[sn] == 0)
{
while(1)
{
pack_len = getSn_RX_RSR(sn);
if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED;
if( (sock_io_mode & (1<<sn)) && (pack_len == 0) ) return SOCK_BUSY;
if(pack_len != 0) break;
MICROPY_THREAD_YIELD();
};
}
sock_pack_info[sn] = PACK_COMPLETED;
switch (mr & 0x07)
{
case Sn_MR_UDP :
if(sock_remained_size[sn] == 0)
{
wiz_recv_data(sn, head, 8);
setSn_CR(sn,Sn_CR_RECV);
while(getSn_CR(sn));
// read peer's IP address, port number & packet length
addr[0] = head[0];
addr[1] = head[1];
addr[2] = head[2];
addr[3] = head[3];
*port = head[4];
*port = (*port << 8) + head[5];
sock_remained_size[sn] = head[6];
sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7];
sock_pack_info[sn] = PACK_FIRST;
}
if(len < sock_remained_size[sn]) pack_len = len;
else pack_len = sock_remained_size[sn];
//
// Need to packet length check (default 1472)
//
wiz_recv_data(sn, buf, pack_len); // data copy.
break;
case Sn_MR_MACRAW :
if(sock_remained_size[sn] == 0)
{
wiz_recv_data(sn, head, 2);
setSn_CR(sn,Sn_CR_RECV);
while(getSn_CR(sn));
// read peer's IP address, port number & packet length
sock_remained_size[sn] = head[0];
sock_remained_size[sn] = (sock_remained_size[sn] <<8) + head[1];
sock_remained_size[sn] -= 2; // len includes 2 len bytes
if(sock_remained_size[sn] > 1514)
{
WIZCHIP_EXPORT(close)(sn);
return SOCKFATAL_PACKLEN;
}
sock_pack_info[sn] = PACK_FIRST;
}
if(len < sock_remained_size[sn]) pack_len = len;
else pack_len = sock_remained_size[sn];
wiz_recv_data(sn,buf,pack_len);
break;
#if ( _WIZCHIP_ < 5200 )
case Sn_MR_IPRAW:
if(sock_remained_size[sn] == 0)
{
wiz_recv_data(sn, head, 6);
setSn_CR(sn,Sn_CR_RECV);
while(getSn_CR(sn));
addr[0] = head[0];
addr[1] = head[1];
addr[2] = head[2];
addr[3] = head[3];
sock_remained_size[sn] = head[4];
sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5];
sock_pack_info[sn] = PACK_FIRST;
}
//
// Need to packet length check
//
if(len < sock_remained_size[sn]) pack_len = len;
else pack_len = sock_remained_size[sn];
wiz_recv_data(sn, buf, pack_len); // data copy.
break;
#endif
default:
wiz_recv_ignore(sn, pack_len); // data copy.
sock_remained_size[sn] = pack_len;
break;
}
setSn_CR(sn,Sn_CR_RECV);
/* wait to process the command... */
while(getSn_CR(sn)) ;
sock_remained_size[sn] -= pack_len;
//M20140501 : replace 0x01 with PACK_REMAINED
//if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01;
if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= PACK_REMAINED;
//
return pack_len;
}
int8_t WIZCHIP_EXPORT(ctlsocket)(uint8_t sn, ctlsock_type cstype, void* arg)
{
uint8_t tmp = 0;
CHECK_SOCKNUM();
switch(cstype)
{
case CS_SET_IOMODE:
tmp = *((uint8_t*)arg);
if(tmp == SOCK_IO_NONBLOCK) sock_io_mode |= (1<<sn);
else if(tmp == SOCK_IO_BLOCK) sock_io_mode &= ~(1<<sn);
else return SOCKERR_ARG;
break;
case CS_GET_IOMODE:
//M20140501 : implict type casting -> explict type casting
//*((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001;
*((uint8_t*)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001);
//
break;
case CS_GET_MAXTXBUF:
*((uint16_t*)arg) = getSn_TxMAX(sn);
break;
case CS_GET_MAXRXBUF:
*((uint16_t*)arg) = getSn_RxMAX(sn);
break;
case CS_CLR_INTERRUPT:
if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG;
setSn_IR(sn,*(uint8_t*)arg);
break;
case CS_GET_INTERRUPT:
*((uint8_t*)arg) = getSn_IR(sn);
break;
case CS_SET_INTMASK:
if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG;
setSn_IMR(sn,*(uint8_t*)arg);
break;
case CS_GET_INTMASK:
*((uint8_t*)arg) = getSn_IMR(sn);
default:
return SOCKERR_ARG;
}
return SOCK_OK;
}
int8_t WIZCHIP_EXPORT(setsockopt)(uint8_t sn, sockopt_type sotype, void* arg)
{
// M20131220 : Remove warning
//uint8_t tmp;
CHECK_SOCKNUM();
switch(sotype)
{
case SO_TTL:
setSn_TTL(sn,*(uint8_t*)arg);
break;
case SO_TOS:
setSn_TOS(sn,*(uint8_t*)arg);
break;
case SO_MSS:
setSn_MSSR(sn,*(uint16_t*)arg);
break;
case SO_DESTIP:
setSn_DIPR(sn, (uint8_t*)arg);
break;
case SO_DESTPORT:
setSn_DPORT(sn, *(uint16_t*)arg);
break;
#if _WIZCHIP_ != 5100
case SO_KEEPALIVESEND:
CHECK_SOCKMODE(Sn_MR_TCP);
#if _WIZCHIP_ > 5200
if(getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT;
#endif
setSn_CR(sn,Sn_CR_SEND_KEEP);
while(getSn_CR(sn) != 0)
{
// M20131220
//if ((tmp = getSn_IR(sn)) & Sn_IR_TIMEOUT)
if (getSn_IR(sn) & Sn_IR_TIMEOUT)
{
setSn_IR(sn, Sn_IR_TIMEOUT);
return SOCKERR_TIMEOUT;
}
}
break;
#if _WIZCHIP_ > 5200
case SO_KEEPALIVEAUTO:
CHECK_SOCKMODE(Sn_MR_TCP);
setSn_KPALVTR(sn,*(uint8_t*)arg);
break;
#endif
#endif
default:
return SOCKERR_ARG;
}
return SOCK_OK;
}
int8_t WIZCHIP_EXPORT(getsockopt)(uint8_t sn, sockopt_type sotype, void* arg)
{
CHECK_SOCKNUM();
switch(sotype)
{
case SO_FLAG:
*(uint8_t*)arg = getSn_MR(sn) & 0xF0;
break;
case SO_TTL:
*(uint8_t*) arg = getSn_TTL(sn);
break;
case SO_TOS:
*(uint8_t*) arg = getSn_TOS(sn);
break;
case SO_MSS:
*(uint8_t*) arg = getSn_MSSR(sn);
case SO_DESTIP:
getSn_DIPR(sn, (uint8_t*)arg);
break;
case SO_DESTPORT:
*(uint16_t*) arg = getSn_DPORT(sn);
break;
#if _WIZCHIP_ > 5200
case SO_KEEPALIVEAUTO:
CHECK_SOCKMODE(Sn_MR_TCP);
*(uint16_t*) arg = getSn_KPALVTR(sn);
break;
#endif
case SO_SENDBUF:
*(uint16_t*) arg = getSn_TX_FSR(sn);
case SO_RECVBUF:
*(uint16_t*) arg = getSn_RX_RSR(sn);
case SO_STATUS:
*(uint8_t*) arg = getSn_SR(sn);
break;
case SO_REMAINSIZE:
if(getSn_MR(sn) == Sn_MR_TCP)
*(uint16_t*)arg = getSn_RX_RSR(sn);
else
*(uint16_t*)arg = sock_remained_size[sn];
break;
case SO_PACKINFO:
CHECK_SOCKMODE(Sn_MR_TCP);
*(uint8_t*)arg = sock_pack_info[sn];
break;
default:
return SOCKERR_SOCKOPT;
}
return SOCK_OK;
}

View file

@ -1,472 +0,0 @@
//*****************************************************************************
//
//! \file socket.h
//! \brief SOCKET APIs Header file.
//! \details SOCKET APIs like as berkeley socket api.
//! \version 1.0.2
//! \date 2013/10/21
//! \par Revision history
//! <2014/05/01> V1.0.2. Refer to M20140501
//! 1. Modify the comment : SO_REMAINED -> PACK_REMAINED
//! 2. Add the comment as zero byte udp data reception in getsockopt().
//! <2013/10/21> 1st Release
//! \author MidnightCow
//! \copyright
//!
//! Copyright (c) 2013, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
/**
* @defgroup WIZnet_socket_APIs 1. WIZnet socket APIs
* @brief WIZnet socket APIs are based on Berkeley socket APIs, thus it has much similar name and interface.
* But there is a little bit of difference.
* @details
* <b> Comparison between WIZnet and Berkeley SOCKET APIs </b>
* <table>
* <tr> <td><b>API</b></td> <td><b>WIZnet</b></td> <td><b>Berkeley</b></td> </tr>
* <tr> <td>socket()</td> <td>O</td> <td>O</td> </tr>
* <tr> <td><b>bind()</b></td> <td>X</td> <td>O</td> </tr>
* <tr> <td><b>listen()</b></td> <td>O</td> <td>O</td> </tr>
* <tr> <td><b>connect()</b></td> <td>O</td> <td>O</td> </tr>
* <tr> <td><b>accept()</b></td> <td>X</td> <td>O</td> </tr>
* <tr> <td><b>recv()</b></td> <td>O</td> <td>O</td> </tr>
* <tr> <td><b>send()</b></td> <td>O</td> <td>O</td> </tr>
* <tr> <td><b>recvfrom()</b></td> <td>O</td> <td>O</td> </tr>
* <tr> <td><b>sendto()</b></td> <td>O</td> <td>O</td> </tr>
* <tr> <td><b>closesocket()</b></td> <td>O<br>close() & disconnect()</td> <td>O</td> </tr>
* </table>
* There are @b bind() and @b accept() functions in @b Berkeley SOCKET API but,
* not in @b WIZnet SOCKET API. Because socket() of WIZnet is not only creating a SOCKET but also binding a local port number,
* and listen() of WIZnet is not only listening to connection request from client but also accepting the connection request. \n
* When you program "TCP SERVER" with Berkeley SOCKET API, you can use only one listen port.
* When the listen SOCKET accepts a connection request from a client, it keeps listening.
* After accepting the connection request, a new SOCKET is created and the new SOCKET is used in communication with the client. \n
* Following figure shows network flow diagram by Berkeley SOCKET API.
* @image html Berkeley_SOCKET.jpg "<Berkeley SOCKET API>"
* But, When you program "TCP SERVER" with WIZnet SOCKET API, you can use as many as 8 listen SOCKET with same port number. \n
* Because there's no accept() in WIZnet SOCKET APIs, when the listen SOCKET accepts a connection request from a client,
* it is changed in order to communicate with the client.
* And the changed SOCKET is not listening any more and is dedicated for communicating with the client. \n
* If there're many listen SOCKET with same listen port number and a client requests a connection,
* the SOCKET which has the smallest SOCKET number accepts the request and is changed as communication SOCKET. \n
* Following figure shows network flow diagram by WIZnet SOCKET API.
* @image html WIZnet_SOCKET.jpg "<WIZnet SOCKET API>"
*/
#ifndef _WIZCHIP_SOCKET_H_
#define _WIZCHIP_SOCKET_H_
// use this macro for exported names to avoid name clashes
#define WIZCHIP_EXPORT(name) wizchip_ ## name
#include "wizchip_conf.h"
#define SOCKET uint8_t ///< SOCKET type define for legacy driver
#define SOCK_OK 1 ///< Result is OK about socket process.
#define SOCK_BUSY 0 ///< Socket is busy on processing the operation. Valid only Non-block IO Mode.
#define SOCK_FATAL -1000 ///< Result is fatal error about socket process.
#define SOCK_ERROR 0
#define SOCKERR_SOCKNUM (SOCK_ERROR - 1) ///< Invalid socket number
#define SOCKERR_SOCKOPT (SOCK_ERROR - 2) ///< Invalid socket option
#define SOCKERR_SOCKINIT (SOCK_ERROR - 3) ///< Socket is not initialized
#define SOCKERR_SOCKCLOSED (SOCK_ERROR - 4) ///< Socket unexpectedly closed.
#define SOCKERR_SOCKMODE (SOCK_ERROR - 5) ///< Invalid socket mode for socket operation.
#define SOCKERR_SOCKFLAG (SOCK_ERROR - 6) ///< Invalid socket flag
#define SOCKERR_SOCKSTATUS (SOCK_ERROR - 7) ///< Invalid socket status for socket operation.
#define SOCKERR_ARG (SOCK_ERROR - 10) ///< Invalid argument.
#define SOCKERR_PORTZERO (SOCK_ERROR - 11) ///< Port number is zero
#define SOCKERR_IPINVALID (SOCK_ERROR - 12) ///< Invalid IP address
#define SOCKERR_TIMEOUT (SOCK_ERROR - 13) ///< Timeout occurred
#define SOCKERR_DATALEN (SOCK_ERROR - 14) ///< Data length is zero or greater than buffer max size.
#define SOCKERR_BUFFER (SOCK_ERROR - 15) ///< Socket buffer is not enough for data communication.
#define SOCKFATAL_PACKLEN (SOCK_FATAL - 1) ///< Invalid packet length. Fatal Error.
/*
* SOCKET FLAG
*/
#define SF_ETHER_OWN (Sn_MR_MFEN) ///< In \ref Sn_MR_MACRAW, Receive only the packet as broadcast, multicast and own packet
#define SF_IGMP_VER2 (Sn_MR_MC) ///< In \ref Sn_MR_UDP with \ref SF_MULTI_ENABLE, Select IGMP version 2.
#define SF_TCP_NODELAY (Sn_MR_ND) ///< In \ref Sn_MR_TCP, Use to nodelayed ack.
#define SF_MULTI_ENABLE (Sn_MR_MULTI) ///< In \ref Sn_MR_UDP, Enable multicast mode.
#if _WIZCHIP_ == 5500
#define SF_BROAD_BLOCK (Sn_MR_BCASTB) ///< In \ref Sn_MR_UDP or \ref Sn_MR_MACRAW, Block broadcast packet. Valid only in W5500
#define SF_MULTI_BLOCK (Sn_MR_MMB) ///< In \ref Sn_MR_MACRAW, Block multicast packet. Valid only in W5500
#define SF_IPv6_BLOCK (Sn_MR_MIP6B) ///< In \ref Sn_MR_MACRAW, Block IPv6 packet. Valid only in W5500
#define SF_UNI_BLOCK (Sn_MR_UCASTB) ///< In \ref Sn_MR_UDP with \ref SF_MULTI_ENABLE. Valid only in W5500
#endif
#define SF_IO_NONBLOCK 0x01 ///< Socket nonblock io mode. It used parameter in \ref socket().
/*
* UDP & MACRAW Packet Infomation
*/
#define PACK_FIRST 0x80 ///< In Non-TCP packet, It indicates to start receiving a packet.
#define PACK_REMAINED 0x01 ///< In Non-TCP packet, It indicates to remain a packet to be received.
#define PACK_COMPLETED 0x00 ///< In Non-TCP packet, It indicates to complete to receive a packet.
// resets all global state associated with the socket interface
void WIZCHIP_EXPORT(socket_reset)(void);
/**
* @ingroup WIZnet_socket_APIs
* @brief Open a socket.
* @details Initializes the socket with 'sn' passed as parameter and open.
*
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @param protocol Protocol type to operate such as TCP, UDP and MACRAW.
* @param port Port number to be bined.
* @param flag Socket flags as \ref SF_ETHER_OWN, \ref SF_IGMP_VER2, \ref SF_TCP_NODELAY, \ref SF_MULTI_ENABLE, \ref SF_IO_NONBLOCK and so on.\n
* Valid flags only in W5500 : @ref SF_BROAD_BLOCK, @ref SF_MULTI_BLOCK, @ref SF_IPv6_BLOCK, and @ref SF_UNI_BLOCK.
* @sa Sn_MR
*
* @return @b Success : The socket number @b 'sn' passed as parameter\n
* @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n
* @ref SOCKERR_SOCKMODE - Not support socket mode as TCP, UDP, and so on. \n
* @ref SOCKERR_SOCKFLAG - Invaild socket flag.
*/
int8_t WIZCHIP_EXPORT(socket)(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag);
/**
* @ingroup WIZnet_socket_APIs
* @brief Close a socket.
* @details It closes the socket with @b'sn' passed as parameter.
*
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
*
* @return @b Success : @ref SOCK_OK \n
* @b Fail : @ref SOCKERR_SOCKNUM - Invalid socket number
*/
int8_t WIZCHIP_EXPORT(close)(uint8_t sn);
/**
* @ingroup WIZnet_socket_APIs
* @brief Listen to a connection request from a client.
* @details It is listening to a connection request from a client.
* If connection request is accepted successfully, the connection is established. Socket sn is used in passive(server) mode.
*
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @return @b Success : @ref SOCK_OK \n
* @b Fail :\n @ref SOCKERR_SOCKINIT - Socket is not initialized \n
* @ref SOCKERR_SOCKCLOSED - Socket closed unexpectedly.
*/
int8_t WIZCHIP_EXPORT(listen)(uint8_t sn);
/**
* @ingroup WIZnet_socket_APIs
* @brief Try to connect a server.
* @details It requests connection to the server with destination IP address and port number passed as parameter.\n
* @note It is valid only in TCP client mode.
* In block io mode, it does not return until connection is completed.
* In Non-block io mode, it return @ref SOCK_BUSY immediately.
*
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @param addr Pointer variable of destination IP address. It should be allocated 4 bytes.
* @param port Destination port number.
*
* @return @b Success : @ref SOCK_OK \n
* @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n
* @ref SOCKERR_SOCKMODE - Invalid socket mode\n
* @ref SOCKERR_SOCKINIT - Socket is not initialized\n
* @ref SOCKERR_IPINVALID - Wrong server IP address\n
* @ref SOCKERR_PORTZERO - Server port zero\n
* @ref SOCKERR_TIMEOUT - Timeout occurred during request connection\n
* @ref SOCK_BUSY - In non-block io mode, it returned immediately\n
*/
int8_t WIZCHIP_EXPORT(connect)(uint8_t sn, uint8_t * addr, uint16_t port);
/**
* @ingroup WIZnet_socket_APIs
* @brief Try to disconnect a connection socket.
* @details It sends request message to disconnect the TCP socket 'sn' passed as parameter to the server or client.
* @note It is valid only in TCP server or client mode. \n
* In block io mode, it does not return until disconnection is completed. \n
* In Non-block io mode, it return @ref SOCK_BUSY immediately. \n
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @return @b Success : @ref SOCK_OK \n
* @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n
* @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
* @ref SOCKERR_TIMEOUT - Timeout occurred \n
* @ref SOCK_BUSY - Socket is busy.
*/
int8_t WIZCHIP_EXPORT(disconnect)(uint8_t sn);
/**
* @ingroup WIZnet_socket_APIs
* @brief Send data to the connected peer in TCP socket.
* @details It is used to send outgoing data to the connected socket.
* @note It is valid only in TCP server or client mode. It can't send data greater than socket buffer size. \n
* In block io mode, It doesn't return until data send is completed - socket buffer size is greater than data. \n
* In non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is not enough. \n
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @param buf Pointer buffer containing data to be sent.
* @param len The byte length of data in buf.
* @return @b Success : The sent data size \n
* @b Fail : \n @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n
* @ref SOCKERR_TIMEOUT - Timeout occurred \n
* @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
* @ref SOCKERR_SOCKNUM - Invalid socket number \n
* @ref SOCKERR_DATALEN - zero data length \n
* @ref SOCK_BUSY - Socket is busy.
*/
int32_t WIZCHIP_EXPORT(send)(uint8_t sn, uint8_t * buf, uint16_t len);
/**
* @ingroup WIZnet_socket_APIs
* @brief Receive data from the connected peer.
* @details It is used to read incoming data from the connected socket.\n
* It waits for data as much as the application wants to receive.
* @note It is valid only in TCP server or client mode. It can't receive data greater than socket buffer size. \n
* In block io mode, it doesn't return until data reception is completed - data is filled as <I>len</I> in socket buffer. \n
* In non-block io mode, it return @ref SOCK_BUSY immediately when <I>len</I> is greater than data size in socket buffer. \n
*
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @param buf Pointer buffer to read incoming data.
* @param len The max data length of data in buf.
* @return @b Success : The real received data size \n
* @b Fail :\n
* @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n
* @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
* @ref SOCKERR_SOCKNUM - Invalid socket number \n
* @ref SOCKERR_DATALEN - zero data length \n
* @ref SOCK_BUSY - Socket is busy.
*/
int32_t WIZCHIP_EXPORT(recv)(uint8_t sn, uint8_t * buf, uint16_t len);
/**
* @ingroup WIZnet_socket_APIs
* @brief Sends datagram to the peer with destination IP address and port number passed as parameter.
* @details It sends datagram of UDP or MACRAW to the peer with destination IP address and port number passed as parameter.\n
* Even if the connectionless socket has been previously connected to a specific address,
* the address and port number parameters override the destination address for that particular datagram only.
* @note In block io mode, It doesn't return until data send is completed - socket buffer size is greater than <I>len</I>.
* In non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is not enough.
*
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @param buf Pointer buffer to send outgoing data.
* @param len The byte length of data in buf.
* @param addr Pointer variable of destination IP address. It should be allocated 4 bytes.
* @param port Destination port number.
*
* @return @b Success : The sent data size \n
* @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n
* @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
* @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n
* @ref SOCKERR_DATALEN - zero data length \n
* @ref SOCKERR_IPINVALID - Wrong server IP address\n
* @ref SOCKERR_PORTZERO - Server port zero\n
* @ref SOCKERR_SOCKCLOSED - Socket unexpectedly closed \n
* @ref SOCKERR_TIMEOUT - Timeout occurred \n
* @ref SOCK_BUSY - Socket is busy.
*/
int32_t WIZCHIP_EXPORT(sendto)(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port);
/**
* @ingroup WIZnet_socket_APIs
* @brief Receive datagram of UDP or MACRAW
* @details This function is an application I/F function which is used to receive the data in other then TCP mode. \n
* This function is used to receive UDP and MAC_RAW mode, and handle the header as well.
* This function can divide to received the packet data.
* On the MACRAW SOCKET, the addr and port parameters are ignored.
* @note In block io mode, it doesn't return until data reception is completed - data is filled as <I>len</I> in socket buffer
* In non-block io mode, it return @ref SOCK_BUSY immediately when <I>len</I> is greater than data size in socket buffer.
*
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @param buf Pointer buffer to read incoming data.
* @param len The max data length of data in buf.
* When the received packet size <= len, receives data as packet sized.
* When others, receives data as len.
* @param addr Pointer variable of destination IP address. It should be allocated 4 bytes.
* It is valid only when the first call recvfrom for receiving the packet.
* When it is valid, @ref packinfo[7] should be set as '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo).
* @param port Pointer variable of destination port number.
* It is valid only when the first call recvform for receiving the packet.
* When it is valid, @ref packinfo[7] should be set as '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo).
*
* @return @b Success : This function return real received data size for success.\n
* @b Fail : @ref SOCKERR_DATALEN - zero data length \n
* @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
* @ref SOCKERR_SOCKNUM - Invalid socket number \n
* @ref SOCKBUSY - Socket is busy.
*/
int32_t WIZCHIP_EXPORT(recvfrom)(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port);
/////////////////////////////
// SOCKET CONTROL & OPTION //
/////////////////////////////
#define SOCK_IO_BLOCK 0 ///< Socket Block IO Mode in @ref setsockopt().
#define SOCK_IO_NONBLOCK 1 ///< Socket Non-block IO Mode in @ref setsockopt().
/**
* @defgroup DATA_TYPE DATA TYPE
*/
/**
* @ingroup DATA_TYPE
* @brief The kind of Socket Interrupt.
* @sa Sn_IR, Sn_IMR, setSn_IR(), getSn_IR(), setSn_IMR(), getSn_IMR()
*/
typedef enum
{
SIK_CONNECTED = (1 << 0), ///< connected
SIK_DISCONNECTED = (1 << 1), ///< disconnected
SIK_RECEIVED = (1 << 2), ///< data received
SIK_TIMEOUT = (1 << 3), ///< timeout occurred
SIK_SENT = (1 << 4), ///< send ok
SIK_ALL = 0x1F, ///< all interrupt
}sockint_kind;
/**
* @ingroup DATA_TYPE
* @brief The type of @ref ctlsocket().
*/
typedef enum
{
CS_SET_IOMODE, ///< set socket IO mode with @ref SOCK_IO_BLOCK or @ref SOCK_IO_NONBLOCK
CS_GET_IOMODE, ///< get socket IO mode
CS_GET_MAXTXBUF, ///< get the size of socket buffer allocated in TX memory
CS_GET_MAXRXBUF, ///< get the size of socket buffer allocated in RX memory
CS_CLR_INTERRUPT, ///< clear the interrupt of socket with @ref sockint_kind
CS_GET_INTERRUPT, ///< get the socket interrupt. refer to @ref sockint_kind
CS_SET_INTMASK, ///< set the interrupt mask of socket with @ref sockint_kind
CS_GET_INTMASK ///< get the masked interrupt of socket. refer to @ref sockint_kind
}ctlsock_type;
/**
* @ingroup DATA_TYPE
* @brief The type of socket option in @ref setsockopt() or @ref getsockopt()
*/
typedef enum
{
SO_FLAG, ///< Valid only in getsockopt(), For set flag of socket refer to <I>flag</I> in @ref socket().
SO_TTL, ///< Set/Get TTL. @ref Sn_TTL ( @ref setSn_TTL(), @ref getSn_TTL() )
SO_TOS, ///< Set/Get TOS. @ref Sn_TOS ( @ref setSn_TOS(), @ref getSn_TOS() )
SO_MSS, ///< Set/Get MSS. @ref Sn_MSSR ( @ref setSn_MSSR(), @ref getSn_MSSR() )
SO_DESTIP, ///< Set/Get the destination IP address. @ref Sn_DIPR ( @ref setSn_DIPR(), @ref getSn_DIPR() )
SO_DESTPORT, ///< Set/Get the destination Port number. @ref Sn_DPORT ( @ref setSn_DPORT(), @ref getSn_DPORT() )
#if _WIZCHIP_ != 5100
SO_KEEPALIVESEND, ///< Valid only in setsockopt. Manually send keep-alive packet in TCP mode
#if _WIZCHIP_ > 5200
SO_KEEPALIVEAUTO, ///< Set/Get keep-alive auto transmission timer in TCP mode
#endif
#endif
SO_SENDBUF, ///< Valid only in getsockopt. Get the free data size of Socekt TX buffer. @ref Sn_TX_FSR, @ref getSn_TX_FSR()
SO_RECVBUF, ///< Valid only in getsockopt. Get the received data size in socket RX buffer. @ref Sn_RX_RSR, @ref getSn_RX_RSR()
SO_STATUS, ///< Valid only in getsockopt. Get the socket status. @ref Sn_SR, @ref getSn_SR()
SO_REMAINSIZE, ///< Valid only in getsockopt. Get the remained packet size in other then TCP mode.
SO_PACKINFO ///< Valid only in getsockopt. Get the packet information as @ref PACK_FIRST, @ref PACK_REMAINED, and @ref PACK_COMPLETED in other then TCP mode.
}sockopt_type;
/**
* @ingroup WIZnet_socket_APIs
* @brief Control socket.
* @details Control IO mode, Interrupt & Mask of socket and get the socket buffer information.
* Refer to @ref ctlsock_type.
* @param sn socket number
* @param cstype type of control socket. refer to @ref ctlsock_type.
* @param arg Data type and value is determined according to @ref ctlsock_type. \n
* <table>
* <tr> <td> @b cstype </td> <td> @b data type</td><td>@b value</td></tr>
* <tr> <td> @ref CS_SET_IOMODE \n @ref CS_GET_IOMODE </td> <td> uint8_t </td><td>@ref SOCK_IO_BLOCK @ref SOCK_IO_NONBLOCK</td></tr>
* <tr> <td> @ref CS_GET_MAXTXBUF \n @ref CS_GET_MAXRXBUF </td> <td> uint16_t </td><td> 0 ~ 16K </td></tr>
* <tr> <td> @ref CS_CLR_INTERRUPT \n @ref CS_GET_INTERRUPT \n @ref CS_SET_INTMASK \n @ref CS_GET_INTMASK </td> <td> @ref sockint_kind </td><td> @ref SIK_CONNECTED, etc. </td></tr>
* </table>
* @return @b Success @ref SOCK_OK \n
* @b fail @ref SOCKERR_ARG - Invalid argument\n
*/
int8_t WIZCHIP_EXPORT(ctlsocket)(uint8_t sn, ctlsock_type cstype, void* arg);
/**
* @ingroup WIZnet_socket_APIs
* @brief set socket options
* @details Set socket option like as TTL, MSS, TOS, and so on. Refer to @ref sockopt_type.
*
* @param sn socket number
* @param sotype socket option type. refer to @ref sockopt_type
* @param arg Data type and value is determined according to <I>sotype</I>. \n
* <table>
* <tr> <td> @b sotype </td> <td> @b data type</td><td>@b value</td></tr>
* <tr> <td> @ref SO_TTL </td> <td> uint8_t </td><td> 0 ~ 255 </td> </tr>
* <tr> <td> @ref SO_TOS </td> <td> uint8_t </td><td> 0 ~ 255 </td> </tr>
* <tr> <td> @ref SO_MSS </td> <td> uint16_t </td><td> 0 ~ 65535 </td> </tr>
* <tr> <td> @ref SO_DESTIP </td> <td> uint8_t[4] </td><td> </td></tr>
* <tr> <td> @ref SO_DESTPORT </td> <td> uint16_t </td><td> 0 ~ 65535 </td></tr>
* <tr> <td> @ref SO_KEEPALIVESEND </td> <td> null </td><td> null </td></tr>
* <tr> <td> @ref SO_KEEPALIVEAUTO </td> <td> uint8_t </td><td> 0 ~ 255 </td></tr>
* </table>
* @return
* - @b Success : @ref SOCK_OK \n
* - @b Fail
* - @ref SOCKERR_SOCKNUM - Invalid Socket number \n
* - @ref SOCKERR_SOCKMODE - Invalid socket mode \n
* - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n
* - @ref SOCKERR_TIMEOUT - Timeout occurred when sending keep-alive packet \n
*/
int8_t WIZCHIP_EXPORT(setsockopt)(uint8_t sn, sockopt_type sotype, void* arg);
/**
* @ingroup WIZnet_socket_APIs
* @brief get socket options
* @details Get socket option like as FLAG, TTL, MSS, and so on. Refer to @ref sockopt_type
* @param sn socket number
* @param sotype socket option type. refer to @ref sockopt_type
* @param arg Data type and value is determined according to <I>sotype</I>. \n
* <table>
* <tr> <td> @b sotype </td> <td>@b data type</td><td>@b value</td></tr>
* <tr> <td> @ref SO_FLAG </td> <td> uint8_t </td><td> @ref SF_ETHER_OWN, etc... </td> </tr>
* <tr> <td> @ref SO_TOS </td> <td> uint8_t </td><td> 0 ~ 255 </td> </tr>
* <tr> <td> @ref SO_MSS </td> <td> uint16_t </td><td> 0 ~ 65535 </td> </tr>
* <tr> <td> @ref SO_DESTIP </td> <td> uint8_t[4] </td><td> </td></tr>
* <tr> <td> @ref SO_DESTPORT </td> <td> uint16_t </td><td> </td></tr>
* <tr> <td> @ref SO_KEEPALIVEAUTO </td> <td> uint8_t </td><td> 0 ~ 255 </td></tr>
* <tr> <td> @ref SO_SENDBUF </td> <td> uint16_t </td><td> 0 ~ 65535 </td></tr>
* <tr> <td> @ref SO_RECVBUF </td> <td> uint16_t </td><td> 0 ~ 65535 </td></tr>
* <tr> <td> @ref SO_STATUS </td> <td> uint8_t </td><td> @ref SOCK_ESTABLISHED, etc.. </td></tr>
* <tr> <td> @ref SO_REMAINSIZE </td> <td> uint16_t </td><td> 0~ 65535 </td></tr>
* <tr> <td> @ref SO_PACKINFO </td> <td> uint8_t </td><td> @ref PACK_FIRST, etc... </td></tr>
* </table>
* @return
* - @b Success : @ref SOCK_OK \n
* - @b Fail
* - @ref SOCKERR_SOCKNUM - Invalid Socket number \n
* - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n
* - @ref SOCKERR_SOCKMODE - Invalid socket mode \n
* @note
* The option as PACK_REMAINED and SO_PACKINFO is valid only in NON-TCP mode and after call @ref recvfrom(). \n
* When SO_PACKINFO value is PACK_FIRST and the return value of recvfrom() is zero,
* This means the zero byte UDP data(UDP Header only) received.
*/
int8_t WIZCHIP_EXPORT(getsockopt)(uint8_t sn, sockopt_type sotype, void* arg);
#endif // _WIZCHIP_SOCKET_H_

View file

@ -1,206 +0,0 @@
// dpgeorge: this file taken from w5500/w5500.c and adapted to W5200
//*****************************************************************************
//
//! \file w5500.c
//! \brief W5500 HAL Interface.
//! \version 1.0.1
//! \date 2013/10/21
//! \par Revision history
//! <2014/05/01> V1.0.2
//! 1. Implicit type casting -> Explicit type casting. Refer to M20140501
//! Fixed the problem on porting into under 32bit MCU
//! Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh
//! Thank for your interesting and serious advices.
//! <2013/10/21> 1st Release
//! <2013/12/20> V1.0.1
//! 1. Remove warning
//! 2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case _WIZCHIP_IO_MODE_SPI_FDM_
//! for loop optimized(removed). refer to M20131220
//! \author MidnightCow
//! \copyright
//!
//! Copyright (c) 2013, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
#include "w5200.h"
#define SMASK (0x7ff) /* tx buffer mask */
#define RMASK (0x7ff) /* rx buffer mask */
#define SSIZE (2048) /* max tx buffer size */
#define RSIZE (2048) /* max rx buffer size */
#define TXBUF_BASE (0x8000)
#define RXBUF_BASE (0xc000)
#define SBASE(sn) (TXBUF_BASE + SSIZE * (sn)) /* tx buffer base for socket sn */
#define RBASE(sn) (RXBUF_BASE + RSIZE * (sn)) /* rx buffer base for socket sn */
uint8_t WIZCHIP_READ(uint32_t AddrSel) {
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
uint8_t spi_data[4] = {
AddrSel >> 8,
AddrSel,
0x00,
0x01,
};
WIZCHIP.IF.SPI._write_bytes(spi_data, 4);
uint8_t ret;
WIZCHIP.IF.SPI._read_bytes(&ret, 1);
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
return ret;
}
void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb) {
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
uint8_t spi_data[5] = {
AddrSel >> 8,
AddrSel,
0x80,
0x01,
wb,
};
WIZCHIP.IF.SPI._write_bytes(spi_data, 5);
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
}
void WIZCHIP_READ_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len) {
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
uint8_t spi_data[4] = {
AddrSel >> 8,
AddrSel,
0x00 | ((len >> 8) & 0x7f),
len & 0xff,
};
WIZCHIP.IF.SPI._write_bytes(spi_data, 4);
WIZCHIP.IF.SPI._read_bytes(pBuf, len);
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
}
void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len) {
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
uint8_t spi_data[4] = {
AddrSel >> 8,
AddrSel,
0x80 | ((len >> 8) & 0x7f),
len & 0xff,
};
WIZCHIP.IF.SPI._write_bytes(spi_data, 4);
WIZCHIP.IF.SPI._write_bytes(pBuf, len);
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
}
uint16_t getSn_TX_FSR(uint8_t sn) {
uint16_t val = 0, val1 = 0;
do {
val1 = (WIZCHIP_READ(Sn_TX_FSR(sn)) << 8) | WIZCHIP_READ(Sn_TX_FSR(sn) + 1);
if (val1 != 0) {
val = (WIZCHIP_READ(Sn_TX_FSR(sn)) << 8) | WIZCHIP_READ(Sn_TX_FSR(sn) + 1);
}
} while (val != val1);
return val;
}
uint16_t getSn_RX_RSR(uint8_t sn) {
uint16_t val = 0, val1 = 0;
do {
val1 = (WIZCHIP_READ(Sn_RX_RSR(sn)) << 8) | WIZCHIP_READ(Sn_RX_RSR(sn) + 1);
if (val1 != 0) {
val = (WIZCHIP_READ(Sn_RX_RSR(sn)) << 8) | WIZCHIP_READ(Sn_RX_RSR(sn) + 1);
}
} while (val != val1);
return val;
}
void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len) {
if (len == 0) {
return;
}
uint16_t ptr = getSn_TX_WR(sn);
uint16_t offset = ptr & SMASK;
uint32_t addr = offset + SBASE(sn);
if (offset + len > SSIZE) {
// implement wrap-around circular buffer
uint16_t size = SSIZE - offset;
WIZCHIP_WRITE_BUF(addr, wizdata, size);
WIZCHIP_WRITE_BUF(SBASE(sn), wizdata + size, len - size);
} else {
WIZCHIP_WRITE_BUF(addr, wizdata, len);
}
ptr += len;
setSn_TX_WR(sn, ptr);
}
void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len) {
if (len == 0) {
return;
}
uint16_t ptr = getSn_RX_RD(sn);
uint16_t offset = ptr & RMASK;
uint16_t addr = RBASE(sn) + offset;
if (offset + len > RSIZE) {
// implement wrap-around circular buffer
uint16_t size = RSIZE - offset;
WIZCHIP_READ_BUF(addr, wizdata, size);
WIZCHIP_READ_BUF(RBASE(sn), wizdata + size, len - size);
} else {
WIZCHIP_READ_BUF(addr, wizdata, len);
}
ptr += len;
setSn_RX_RD(sn, ptr);
}
void wiz_recv_ignore(uint8_t sn, uint16_t len) {
uint16_t ptr = getSn_RX_RD(sn);
ptr += len;
setSn_RX_RD(sn, ptr);
}

File diff suppressed because it is too large Load diff

View file

@ -1,246 +0,0 @@
//*****************************************************************************
//
//! \file w5500.c
//! \brief W5500 HAL Interface.
//! \version 1.0.1
//! \date 2013/10/21
//! \par Revision history
//! <2014/05/01> V1.0.2
//! 1. Implicit type casting -> Explicit type casting. Refer to M20140501
//! Fixed the problem on porting into under 32bit MCU
//! Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh
//! Thank for your interesting and serious advices.
//! <2013/10/21> 1st Release
//! <2013/12/20> V1.0.1
//! 1. Remove warning
//! 2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case _WIZCHIP_IO_MODE_SPI_FDM_
//! for loop optimized(removed). refer to M20131220
//! \author MidnightCow
//! \copyright
//!
//! Copyright (c) 2013, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
//#include <stdio.h>
#include "w5500.h"
#define _W5500_SPI_VDM_OP_ 0x00
#define _W5500_SPI_FDM_OP_LEN1_ 0x01
#define _W5500_SPI_FDM_OP_LEN2_ 0x02
#define _W5500_SPI_FDM_OP_LEN4_ 0x03
////////////////////////////////////////////////////
#define LPC_SSP0 (0)
static void Chip_SSP_ReadFrames_Blocking(int dummy, uint8_t *buf, uint32_t len) {
WIZCHIP.IF.SPI._read_bytes(buf, len);
}
static void Chip_SSP_WriteFrames_Blocking(int dummy, const uint8_t *buf, uint32_t len) {
WIZCHIP.IF.SPI._write_bytes(buf, len);
}
uint8_t WIZCHIP_READ(uint32_t AddrSel)
{
uint8_t ret;
uint8_t spi_data[3];
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
//ret = WIZCHIP.IF.SPI._read_byte();
spi_data[0] = (AddrSel & 0x00FF0000) >> 16;
spi_data[1] = (AddrSel & 0x0000FF00) >> 8;
spi_data[2] = (AddrSel & 0x000000FF) >> 0;
Chip_SSP_WriteFrames_Blocking(LPC_SSP0, spi_data, 3);
Chip_SSP_ReadFrames_Blocking(LPC_SSP0, &ret, 1);
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
return ret;
}
void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb )
{
uint8_t spi_data[4];
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
//WIZCHIP.IF.SPI._write_byte(wb);
spi_data[0] = (AddrSel & 0x00FF0000) >> 16;
spi_data[1] = (AddrSel & 0x0000FF00) >> 8;
spi_data[2] = (AddrSel & 0x000000FF) >> 0;
spi_data[3] = wb;
Chip_SSP_WriteFrames_Blocking(LPC_SSP0, spi_data, 4);
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
}
void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
{
uint8_t spi_data[3];
//uint16_t i;
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
//for(i = 0; i < len; i++)
// pBuf[i] = WIZCHIP.IF.SPI._read_byte();
spi_data[0] = (AddrSel & 0x00FF0000) >> 16;
spi_data[1] = (AddrSel & 0x0000FF00) >> 8;
spi_data[2] = (AddrSel & 0x000000FF) >> 0;
Chip_SSP_WriteFrames_Blocking(LPC_SSP0, spi_data, 3);
Chip_SSP_ReadFrames_Blocking(LPC_SSP0, pBuf, len);
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
}
void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
{
uint8_t spi_data[3];
//uint16_t i;
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
//for(i = 0; i < len; i++)
// WIZCHIP.IF.SPI._write_byte(pBuf[i]);
spi_data[0] = (AddrSel & 0x00FF0000) >> 16;
spi_data[1] = (AddrSel & 0x0000FF00) >> 8;
spi_data[2] = (AddrSel & 0x000000FF) >> 0;
Chip_SSP_WriteFrames_Blocking(LPC_SSP0, spi_data, 3);
Chip_SSP_WriteFrames_Blocking(LPC_SSP0, pBuf, len);
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
}
uint16_t getSn_TX_FSR(uint8_t sn)
{
uint16_t val=0,val1=0;
do
{
val1 = WIZCHIP_READ(Sn_TX_FSR(sn));
val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
if (val1 != 0)
{
val = WIZCHIP_READ(Sn_TX_FSR(sn));
val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
}
}while (val != val1);
return val;
}
uint16_t getSn_RX_RSR(uint8_t sn)
{
uint16_t val=0,val1=0;
do
{
val1 = WIZCHIP_READ(Sn_RX_RSR(sn));
val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
if (val1 != 0)
{
val = WIZCHIP_READ(Sn_RX_RSR(sn));
val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
}
}while (val != val1);
return val;
}
void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
{
uint16_t ptr = 0;
uint32_t addrsel = 0;
if(len == 0) return;
ptr = getSn_TX_WR(sn);
//M20140501 : implict type casting -> explict type casting
//addrsel = (ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3);
addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3);
//
WIZCHIP_WRITE_BUF(addrsel,wizdata, len);
ptr += len;
setSn_TX_WR(sn,ptr);
}
void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
{
uint16_t ptr = 0;
uint32_t addrsel = 0;
if(len == 0) return;
ptr = getSn_RX_RD(sn);
//M20140501 : implict type casting -> explict type casting
//addrsel = ((ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3);
addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3);
//
WIZCHIP_READ_BUF(addrsel, wizdata, len);
ptr += len;
setSn_RX_RD(sn,ptr);
}
void wiz_recv_ignore(uint8_t sn, uint16_t len)
{
uint16_t ptr = 0;
ptr = getSn_RX_RD(sn);
ptr += len;
setSn_RX_RD(sn,ptr);
}

File diff suppressed because it is too large Load diff

View file

@ -1,662 +0,0 @@
//****************************************************************************/
//!
//! \file wizchip_conf.c
//! \brief WIZCHIP Config Header File.
//! \version 1.0.1
//! \date 2013/10/21
//! \par Revision history
//! <2014/05/01> V1.0.1 Refer to M20140501
//! 1. Explicit type casting in wizchip_bus_readbyte() & wizchip_bus_writebyte()
// Issued by Mathias ClauBen.
//! uint32_t type converts into ptrdiff_t first. And then recoverting it into uint8_t*
//! For remove the warning when pointer type size is not 32bit.
//! If ptrdiff_t doesn't support in your complier, You should must replace ptrdiff_t into your suitable pointer type.
//! <2013/10/21> 1st Release
//! \author MidnightCow
//! \copyright
//!
//! Copyright (c) 2013, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************/
//A20140501 : for use the type - ptrdiff_t
#include <stddef.h>
//
#include "wizchip_conf.h"
#include "socket.h"
/**
* @brief Default function to enable interrupt.
* @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called.
*/
void wizchip_cris_enter(void) {};
/**
* @brief Default function to disable interrupt.
* @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called.
*/
void wizchip_cris_exit(void) {};
/**
* @brief Default function to select chip.
* @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called.
*/
void wizchip_cs_select(void) {};
/**
* @brief Default function to deselect chip.
* @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called.
*/
void wizchip_cs_deselect(void) {};
/**
* @brief Default function to read in direct or indirect interface.
* @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called.
*/
//M20140501 : Explict pointer type casting
//uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t *) AddrSel); };
uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t *)((ptrdiff_t) AddrSel)); };
/**
* @brief Default function to write in direct or indirect interface.
* @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called.
*/
//M20140501 : Explict pointer type casting
//void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile uint8_t*) AddrSel) = wb; };
void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile uint8_t*)((ptrdiff_t)AddrSel)) = wb; };
/**
* @brief Default function to read in SPI interface.
* @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called.
*/
void wizchip_spi_readbytes(uint8_t *buf, uint32_t len) {}
/**
* @brief Default function to write in SPI interface.
* @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called.
*/
void wizchip_spi_writebytes(const uint8_t *buf, uint32_t len) {}
/**
* @\ref _WIZCHIP instance
*/
_WIZCHIP WIZCHIP =
{
.id = _WIZCHIP_ID_,
.if_mode = _WIZCHIP_IO_MODE_,
.CRIS._enter = wizchip_cris_enter,
.CRIS._exit = wizchip_cris_exit,
.CS._select = wizchip_cs_select,
.CS._deselect = wizchip_cs_deselect,
.IF.BUS._read_byte = wizchip_bus_readbyte,
.IF.BUS._write_byte = wizchip_bus_writebyte
// .IF.SPI._read_byte = wizchip_spi_readbyte,
// .IF.SPI._write_byte = wizchip_spi_writebyte
};
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
static uint8_t _SUBN_[4]; // subnet
#endif
static uint8_t _DNS_[4]; // DNS server ip address
static dhcp_mode _DHCP_; // DHCP mode
void reg_wizchip_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void))
{
if(!cris_en || !cris_ex)
{
WIZCHIP.CRIS._enter = wizchip_cris_enter;
WIZCHIP.CRIS._exit = wizchip_cris_exit;
}
else
{
WIZCHIP.CRIS._enter = cris_en;
WIZCHIP.CRIS._exit = cris_ex;
}
}
void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void))
{
if(!cs_sel || !cs_desel)
{
WIZCHIP.CS._select = wizchip_cs_select;
WIZCHIP.CS._deselect = wizchip_cs_deselect;
}
else
{
WIZCHIP.CS._select = cs_sel;
WIZCHIP.CS._deselect = cs_desel;
}
}
void reg_wizchip_bus_cbfunc(uint8_t(*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb))
{
while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_BUS_));
if(!bus_rb || !bus_wb)
{
WIZCHIP.IF.BUS._read_byte = wizchip_bus_readbyte;
WIZCHIP.IF.BUS._write_byte = wizchip_bus_writebyte;
}
else
{
WIZCHIP.IF.BUS._read_byte = bus_rb;
WIZCHIP.IF.BUS._write_byte = bus_wb;
}
}
void reg_wizchip_spi_cbfunc(void (*spi_rb)(uint8_t *, uint32_t), void (*spi_wb)(const uint8_t *, uint32_t))
{
while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_));
if(!spi_rb || !spi_wb)
{
WIZCHIP.IF.SPI._read_bytes = wizchip_spi_readbytes;
WIZCHIP.IF.SPI._write_bytes = wizchip_spi_writebytes;
}
else
{
WIZCHIP.IF.SPI._read_bytes = spi_rb;
WIZCHIP.IF.SPI._write_bytes = spi_wb;
}
}
int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg)
{
uint8_t tmp = 0;
uint8_t* ptmp[2] = {0,0};
switch(cwtype)
{
case CW_RESET_WIZCHIP:
wizchip_sw_reset();
break;
case CW_INIT_WIZCHIP:
if(arg != 0)
{
ptmp[0] = (uint8_t*)arg;
ptmp[1] = ptmp[0] + _WIZCHIP_SOCK_NUM_;
}
return wizchip_init(ptmp[0], ptmp[1]);
case CW_CLR_INTERRUPT:
wizchip_clrinterrupt(*((intr_kind*)arg));
break;
case CW_GET_INTERRUPT:
*((intr_kind*)arg) = wizchip_getinterrupt();
break;
case CW_SET_INTRMASK:
wizchip_setinterruptmask(*((intr_kind*)arg));
break;
case CW_GET_INTRMASK:
*((intr_kind*)arg) = wizchip_getinterruptmask();
break;
#if _WIZCHIP_ > 5100
case CW_SET_INTRTIME:
setINTLEVEL(*(uint16_t*)arg);
break;
case CW_GET_INTRTIME:
*(uint16_t*)arg = getINTLEVEL();
break;
#endif
case CW_GET_ID:
((uint8_t*)arg)[0] = WIZCHIP.id[0];
((uint8_t*)arg)[1] = WIZCHIP.id[1];
((uint8_t*)arg)[2] = WIZCHIP.id[2];
((uint8_t*)arg)[3] = WIZCHIP.id[3];
((uint8_t*)arg)[4] = WIZCHIP.id[4];
((uint8_t*)arg)[5] = 0;
break;
#if _WIZCHIP_ == 5500
case CW_RESET_PHY:
wizphy_reset();
break;
case CW_SET_PHYCONF:
wizphy_setphyconf((wiz_PhyConf*)arg);
break;
case CW_GET_PHYCONF:
wizphy_getphyconf((wiz_PhyConf*)arg);
break;
case CW_GET_PHYSTATUS:
break;
case CW_SET_PHYPOWMODE:
return wizphy_setphypmode(*(uint8_t*)arg);
#endif
case CW_GET_PHYPOWMODE:
tmp = wizphy_getphypmode();
if((int8_t)tmp == -1) return -1;
*(uint8_t*)arg = tmp;
break;
case CW_GET_PHYLINK:
tmp = wizphy_getphylink();
if((int8_t)tmp == -1) return -1;
*(uint8_t*)arg = tmp;
break;
default:
return -1;
}
return 0;
}
int8_t ctlnetwork(ctlnetwork_type cntype, void* arg)
{
switch(cntype)
{
case CN_SET_NETINFO:
wizchip_setnetinfo((wiz_NetInfo*)arg);
break;
case CN_GET_NETINFO:
wizchip_getnetinfo((wiz_NetInfo*)arg);
break;
case CN_SET_NETMODE:
return wizchip_setnetmode(*(netmode_type*)arg);
case CN_GET_NETMODE:
*(netmode_type*)arg = wizchip_getnetmode();
break;
case CN_SET_TIMEOUT:
wizchip_settimeout((wiz_NetTimeout*)arg);
break;
case CN_GET_TIMEOUT:
wizchip_gettimeout((wiz_NetTimeout*)arg);
break;
default:
return -1;
}
return 0;
}
void wizchip_sw_reset(void)
{
uint8_t gw[4], sn[4], sip[4];
uint8_t mac[6];
getSHAR(mac);
getGAR(gw); getSUBR(sn); getSIPR(sip);
setMR(MR_RST);
getMR(); // for delay
setSHAR(mac);
setGAR(gw);
setSUBR(sn);
setSIPR(sip);
}
int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize)
{
int8_t i;
int8_t tmp = 0;
wizchip_sw_reset();
if(txsize)
{
tmp = 0;
for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
tmp += txsize[i];
if(tmp > 16) return -1;
for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
setSn_TXBUF_SIZE(i, txsize[i]);
}
if(rxsize)
{
tmp = 0;
for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
tmp += rxsize[i];
if(tmp > 16) return -1;
for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
setSn_RXBUF_SIZE(i, rxsize[i]);
}
WIZCHIP_EXPORT(socket_reset)();
return 0;
}
void wizchip_clrinterrupt(intr_kind intr)
{
uint8_t ir = (uint8_t)intr;
uint8_t sir = (uint8_t)((uint16_t)intr >> 8);
#if _WIZCHIP_ < 5500
ir |= (1<<4); // IK_WOL
#endif
#if _WIZCHIP_ == 5200
ir |= (1 << 6);
#endif
#if _WIZCHIP_ < 5200
sir &= 0x0F;
#endif
#if _WIZCHIP_ == 5100
ir |= sir;
setIR(ir);
#else
setIR(ir);
setSIR(sir);
#endif
}
intr_kind wizchip_getinterrupt(void)
{
uint8_t ir = 0;
uint8_t sir = 0;
uint16_t ret = 0;
#if _WIZCHIP_ == 5100
ir = getIR();
sir = ir 0x0F;
#else
ir = getIR();
sir = getSIR();
#endif
#if _WIZCHIP_ < 5500
ir &= ~(1<<4); // IK_WOL
#endif
#if _WIZCHIP_ == 5200
ir &= ~(1 << 6);
#endif
ret = sir;
ret = (ret << 8) + ir;
return (intr_kind)ret;
}
void wizchip_setinterruptmask(intr_kind intr)
{
uint8_t imr = (uint8_t)intr;
uint8_t simr = (uint8_t)((uint16_t)intr >> 8);
#if _WIZCHIP_ < 5500
imr &= ~(1<<4); // IK_WOL
#endif
#if _WIZCHIP_ == 5200
imr &= ~(1 << 6);
#endif
#if _WIZCHIP_ < 5200
simr &= 0x0F;
#endif
#if _WIZCHIP_ == 5100
imr |= simr;
setIMR(imr);
#else
setIMR(imr);
setSIMR(simr);
#endif
}
intr_kind wizchip_getinterruptmask(void)
{
uint8_t imr = 0;
uint8_t simr = 0;
uint16_t ret = 0;
#if _WIZCHIP_ == 5100
imr = getIMR();
simr = imr 0x0F;
#else
imr = getIMR();
simr = getSIMR();
#endif
#if _WIZCHIP_ < 5500
imr &= ~(1<<4); // IK_WOL
#endif
#if _WIZCHIP_ == 5200
imr &= ~(1 << 6); // IK_DEST_UNREACH
#endif
ret = simr;
ret = (ret << 8) + imr;
return (intr_kind)ret;
}
int8_t wizphy_getphylink(void)
{
int8_t tmp;
#if _WIZCHIP_ == 5200
if(getPHYSTATUS() & PHYSTATUS_LINK)
tmp = PHY_LINK_ON;
else
tmp = PHY_LINK_OFF;
#elif _WIZCHIP_ == 5500
if(getPHYCFGR() & PHYCFGR_LNK_ON)
tmp = PHY_LINK_ON;
else
tmp = PHY_LINK_OFF;
#else
tmp = -1;
#endif
return tmp;
}
#if _WIZCHIP_ > 5100
int8_t wizphy_getphypmode(void)
{
int8_t tmp = 0;
#if _WIZCHIP_ == 5200
if(getPHYSTATUS() & PHYSTATUS_POWERDOWN)
tmp = PHY_POWER_DOWN;
else
tmp = PHY_POWER_NORM;
#elif _WIZCHIP_ == 5500
if(getPHYCFGR() & PHYCFGR_OPMDC_PDOWN)
tmp = PHY_POWER_DOWN;
else
tmp = PHY_POWER_NORM;
#else
tmp = -1;
#endif
return tmp;
}
#endif
#if _WIZCHIP_ == 5500
void wizphy_reset(void)
{
uint8_t tmp = getPHYCFGR();
tmp &= PHYCFGR_RST;
setPHYCFGR(tmp);
tmp = getPHYCFGR();
tmp |= ~PHYCFGR_RST;
setPHYCFGR(tmp);
}
void wizphy_setphyconf(wiz_PhyConf* phyconf)
{
uint8_t tmp = 0;
if(phyconf->by == PHY_CONFBY_SW)
tmp |= PHYCFGR_OPMD;
else
tmp &= ~PHYCFGR_OPMD;
if(phyconf->mode == PHY_MODE_AUTONEGO)
tmp |= PHYCFGR_OPMDC_ALLA;
else
{
if(phyconf->duplex == PHY_DUPLEX_FULL)
{
if(phyconf->speed == PHY_SPEED_100)
tmp |= PHYCFGR_OPMDC_100F;
else
tmp |= PHYCFGR_OPMDC_10F;
}
else
{
if(phyconf->speed == PHY_SPEED_100)
tmp |= PHYCFGR_OPMDC_100H;
else
tmp |= PHYCFGR_OPMDC_10H;
}
}
setPHYCFGR(tmp);
wizphy_reset();
}
void wizphy_getphyconf(wiz_PhyConf* phyconf)
{
uint8_t tmp = 0;
tmp = getPHYCFGR();
phyconf->by = (tmp & PHYCFGR_OPMD) ? PHY_CONFBY_SW : PHY_CONFBY_HW;
switch(tmp & PHYCFGR_OPMDC_ALLA)
{
case PHYCFGR_OPMDC_ALLA:
case PHYCFGR_OPMDC_100FA:
phyconf->mode = PHY_MODE_AUTONEGO;
break;
default:
phyconf->mode = PHY_MODE_MANUAL;
break;
}
switch(tmp & PHYCFGR_OPMDC_ALLA)
{
case PHYCFGR_OPMDC_100FA:
case PHYCFGR_OPMDC_100F:
case PHYCFGR_OPMDC_100H:
phyconf->speed = PHY_SPEED_100;
break;
default:
phyconf->speed = PHY_SPEED_10;
break;
}
switch(tmp & PHYCFGR_OPMDC_ALLA)
{
case PHYCFGR_OPMDC_100FA:
case PHYCFGR_OPMDC_100F:
case PHYCFGR_OPMDC_10F:
phyconf->duplex = PHY_DUPLEX_FULL;
break;
default:
phyconf->duplex = PHY_DUPLEX_HALF;
break;
}
}
void wizphy_getphystat(wiz_PhyConf* phyconf)
{
uint8_t tmp = getPHYCFGR();
phyconf->duplex = (tmp & PHYCFGR_DPX_FULL) ? PHY_DUPLEX_FULL : PHY_DUPLEX_HALF;
phyconf->speed = (tmp & PHYCFGR_SPD_100) ? PHY_SPEED_100 : PHY_SPEED_10;
}
int8_t wizphy_setphypmode(uint8_t pmode)
{
uint8_t tmp = 0;
tmp = getPHYCFGR();
if((tmp & PHYCFGR_OPMD)== 0) return -1;
tmp &= ~PHYCFGR_OPMDC_ALLA;
if( pmode == PHY_POWER_DOWN)
tmp |= PHYCFGR_OPMDC_PDOWN;
else
tmp |= PHYCFGR_OPMDC_ALLA;
setPHYCFGR(tmp);
wizphy_reset();
tmp = getPHYCFGR();
if( pmode == PHY_POWER_DOWN)
{
if(tmp & PHYCFGR_OPMDC_PDOWN) return 0;
}
else
{
if(tmp & PHYCFGR_OPMDC_ALLA) return 0;
}
return -1;
}
#endif
void wizchip_setnetinfo(wiz_NetInfo* pnetinfo)
{
setSHAR(pnetinfo->mac);
setGAR(pnetinfo->gw);
setSUBR(pnetinfo->sn);
setSIPR(pnetinfo->ip);
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
_SUBN_[0] = pnetinfo->sn[0];
_SUBN_[1] = pnetinfo->sn[1];
_SUBN_[2] = pnetinfo->sn[2];
_SUBN_[3] = pnetinfo->sn[3];
#endif
_DNS_[0] = pnetinfo->dns[0];
_DNS_[1] = pnetinfo->dns[1];
_DNS_[2] = pnetinfo->dns[2];
_DNS_[3] = pnetinfo->dns[3];
_DHCP_ = pnetinfo->dhcp;
}
void wizchip_getnetinfo(wiz_NetInfo* pnetinfo)
{
getSHAR(pnetinfo->mac);
getGAR(pnetinfo->gw);
getSUBR(pnetinfo->sn);
getSIPR(pnetinfo->ip);
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
pnetinfo->sn[0] = _SUBN_[0];
pnetinfo->sn[1] = _SUBN_[1];
pnetinfo->sn[2] = _SUBN_[2];
pnetinfo->sn[3] = _SUBN_[3];
#endif
pnetinfo->dns[0]= _DNS_[0];
pnetinfo->dns[1]= _DNS_[1];
pnetinfo->dns[2]= _DNS_[2];
pnetinfo->dns[3]= _DNS_[3];
pnetinfo->dhcp = _DHCP_;
}
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
uint8_t *wizchip_getsubn(void) {
return _SUBN_;
}
#endif
int8_t wizchip_setnetmode(netmode_type netmode)
{
uint8_t tmp = 0;
#if _WIZCHIP_ != 5500
if(netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK)) return -1;
#else
if(netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK | NM_FORCEARP)) return -1;
#endif
tmp = getMR();
tmp |= (uint8_t)netmode;
setMR(tmp);
return 0;
}
netmode_type wizchip_getnetmode(void)
{
return (netmode_type) getMR();
}
void wizchip_settimeout(wiz_NetTimeout* nettime)
{
setRCR(nettime->retry_cnt);
setRTR(nettime->time_100us);
}
void wizchip_gettimeout(wiz_NetTimeout* nettime)
{
nettime->retry_cnt = getRCR();
nettime->time_100us = getRTR();
}

View file

@ -1,554 +0,0 @@
//*****************************************************************************
//
//! \file wizchip_conf.h
//! \brief WIZCHIP Config Header File.
//! \version 1.0.0
//! \date 2013/10/21
//! \par Revision history
//! <2013/10/21> 1st Release
//! \author MidnightCow
//! \copyright
//!
//! Copyright (c) 2013, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
/**
* @defgroup extra_functions 2. WIZnet Extra Functions
*
* @brief These functions is optional function. It could be replaced at WIZCHIP I/O function because they were made by WIZCHIP I/O functions.
* @details There are functions of configuring WIZCHIP, network, interrupt, phy, network information and timer. \n
*
*/
#ifndef _WIZCHIP_CONF_H_
#define _WIZCHIP_CONF_H_
#include <stdint.h>
/**
* @brief Select WIZCHIP.
* @todo You should select one, \b 5100, \b 5200 ,\b 5500 or etc. \n\n
* ex> <code> #define \_WIZCHIP_ 5500 </code>
*/
#ifndef _WIZCHIP_
#define _WIZCHIP_ 5200 // 5100, 5200, 5500
#endif
#define _WIZCHIP_IO_MODE_NONE_ 0x0000
#define _WIZCHIP_IO_MODE_BUS_ 0x0100 /**< Bus interface mode */
#define _WIZCHIP_IO_MODE_SPI_ 0x0200 /**< SPI interface mode */
//#define _WIZCHIP_IO_MODE_IIC_ 0x0400
//#define _WIZCHIP_IO_MODE_SDIO_ 0x0800
// Add to
//
#define _WIZCHIP_IO_MODE_BUS_DIR_ (_WIZCHIP_IO_MODE_BUS_ + 1) /**< BUS interface mode for direct */
#define _WIZCHIP_IO_MODE_BUS_INDIR_ (_WIZCHIP_IO_MODE_BUS_ + 2) /**< BUS interface mode for indirect */
#define _WIZCHIP_IO_MODE_SPI_VDM_ (_WIZCHIP_IO_MODE_SPI_ + 1) /**< SPI interface mode for variable length data*/
#define _WIZCHIP_IO_MODE_SPI_FDM_ (_WIZCHIP_IO_MODE_SPI_ + 2) /**< SPI interface mode for fixed length data mode*/
#if (_WIZCHIP_ == 5100)
#define _WIZCHIP_ID_ "W5100\0"
/**
* @brief Define interface mode.
* @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_
*/
// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_
// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_
#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_
#elif (_WIZCHIP_ == 5200)
#define _WIZCHIP_ID_ "W5200\0"
/**
* @brief Define interface mode.
* @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_
*/
// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_
#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_
#include "w5200/w5200.h"
#elif (_WIZCHIP_ == 5500)
#define _WIZCHIP_ID_ "W5500\0"
/**
* @brief Define interface mode. \n
* @todo Should select interface mode as chip.
* - @ref \_WIZCHIP_IO_MODE_SPI_ \n
* -@ref \_WIZCHIP_IO_MODE_SPI_VDM_ : Valid only in @ref \_WIZCHIP_ == 5500 \n
* -@ref \_WIZCHIP_IO_MODE_SPI_FDM_ : Valid only in @ref \_WIZCHIP_ == 5500 \n
* - @ref \_WIZCHIP_IO_MODE_BUS_ \n
* - @ref \_WIZCHIP_IO_MODE_BUS_DIR_ \n
* - @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ \n
* - Others will be defined in future. \n\n
* ex> <code> #define \_WIZCHIP_IO_MODE_ \_WIZCHIP_IO_MODE_SPI_VDM_ </code>
*
*/
//#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_FDM_
#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_VDM_
#include "w5500/w5500.h"
#else
#error "Unknown defined _WIZCHIP_. You should define one of 5100, 5200, and 5500 !!!"
#endif
#ifndef _WIZCHIP_IO_MODE_
#error "Undefined _WIZCHIP_IO_MODE_. You should define it !!!"
#endif
/**
* @brief Define I/O base address when BUS IF mode.
* @todo Should re-define it to fit your system when BUS IF Mode (@ref \_WIZCHIP_IO_MODE_BUS_,
* @ref \_WIZCHIP_IO_MODE_BUS_DIR_, @ref \_WIZCHIP_IO_MODE_BUS_INDIR_). \n\n
* ex> <code> #define \_WIZCHIP_IO_BASE_ 0x00008000 </code>
*/
#define _WIZCHIP_IO_BASE_ 0x00000000 //
#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_
#ifndef _WIZCHIP_IO_BASE_
#error "You should be define _WIZCHIP_IO_BASE to fit your system memory map."
#endif
#endif
#if _WIZCHIP_ > 5100
#define _WIZCHIP_SOCK_NUM_ 8 ///< The count of independant socket of @b WIZCHIP
#else
#define _WIZCHIP_SOCK_NUM_ 4 ///< The count of independant socket of @b WIZCHIP
#endif
/********************************************************
* WIZCHIP BASIC IF functions for SPI, SDIO, I2C , ETC.
*********************************************************/
/**
* @ingroup DATA_TYPE
* @brief The set of callback functions for W5500:@ref WIZCHIP_IO_Functions W5200:@ref WIZCHIP_IO_Functions_W5200
*/
typedef struct __WIZCHIP
{
uint16_t if_mode; ///< host interface mode
uint8_t id[6]; ///< @b WIZCHIP ID such as @b 5100, @b 5200, @b 5500, and so on.
/**
* The set of critical section callback func.
*/
struct _CRIS
{
void (*_enter) (void); ///< crtical section enter
void (*_exit) (void); ///< critial section exit
}CRIS;
/**
* The set of @ref\_WIZCHIP_ select control callback func.
*/
struct _CS
{
void (*_select) (void); ///< @ref \_WIZCHIP_ selected
void (*_deselect)(void); ///< @ref \_WIZCHIP_ deselected
}CS;
/**
* The set of interface IO callback func.
*/
union _IF
{
/**
* For BUS interface IO
*/
struct
{
uint8_t (*_read_byte) (uint32_t AddrSel);
void (*_write_byte) (uint32_t AddrSel, uint8_t wb);
}BUS;
/**
* For SPI interface IO
*/
struct
{
void (*_read_bytes) (uint8_t *buf, uint32_t len);
void (*_write_bytes) (const uint8_t *buf, uint32_t len);
}SPI;
// To be added
//
}IF;
}_WIZCHIP;
extern _WIZCHIP WIZCHIP;
/**
* @ingroup DATA_TYPE
* WIZCHIP control type enumration used in @ref ctlwizchip().
*/
typedef enum
{
CW_RESET_WIZCHIP, ///< Resets WIZCHIP by softly
CW_INIT_WIZCHIP, ///< Inializes to WIZCHIP with SOCKET buffer size 2 or 1 dimension array typed uint8_t.
CW_GET_INTERRUPT, ///< Get Interrupt status of WIZCHIP
CW_CLR_INTERRUPT, ///< Clears interrupt
CW_SET_INTRMASK, ///< Masks interrupt
CW_GET_INTRMASK, ///< Get interrupt mask
CW_SET_INTRTIME, ///< Set interval time between the current and next interrupt.
CW_GET_INTRTIME, ///< Set interval time between the current and next interrupt.
CW_GET_ID, ///< Gets WIZCHIP name.
#if _WIZCHIP_ == 5500
CW_RESET_PHY, ///< Resets internal PHY. Valid Only W5000
CW_SET_PHYCONF, ///< When PHY configured by interal register, PHY operation mode (Manual/Auto, 10/100, Half/Full). Valid Only W5000
CW_GET_PHYCONF, ///< Get PHY operation mode in interal register. Valid Only W5000
CW_GET_PHYSTATUS, ///< Get real PHY status on operating. Valid Only W5000
CW_SET_PHYPOWMODE, ///< Set PHY power mode as noraml and down when PHYSTATUS.OPMD == 1. Valid Only W5000
#endif
CW_GET_PHYPOWMODE, ///< Get PHY Power mode as down or normal
CW_GET_PHYLINK ///< Get PHY Link status
}ctlwizchip_type;
/**
* @ingroup DATA_TYPE
* Network control type enumration used in @ref ctlnetwork().
*/
typedef enum
{
CN_SET_NETINFO, ///< Set Network with @ref wiz_NetInfo
CN_GET_NETINFO, ///< Get Network with @ref wiz_NetInfo
CN_SET_NETMODE, ///< Set network mode as WOL, PPPoE, Ping Block, and Force ARP mode
CN_GET_NETMODE, ///< Get network mode as WOL, PPPoE, Ping Block, and Force ARP mode
CN_SET_TIMEOUT, ///< Set network timeout as retry count and time.
CN_GET_TIMEOUT, ///< Get network timeout as retry count and time.
}ctlnetwork_type;
/**
* @ingroup DATA_TYPE
* Interrupt kind when CW_SET_INTRRUPT, CW_GET_INTERRUPT, CW_SET_INTRMASK
* and CW_GET_INTRMASK is used in @ref ctlnetwork().
* It can be used with OR operation.
*/
typedef enum
{
#if _WIZCHIP_ > 5200
IK_WOL = (1 << 4), ///< Wake On Lan by receiving the magic packet. Valid in W500.
#endif
IK_PPPOE_TERMINATED = (1 << 5), ///< PPPoE Disconnected
#if _WIZCHIP_ != 5200
IK_DEST_UNREACH = (1 << 6), ///< Destination IP & Port Unreable, No use in W5200
#endif
IK_IP_CONFLICT = (1 << 7), ///< IP conflict occurred
IK_SOCK_0 = (1 << 8), ///< Socket 0 interrupt
IK_SOCK_1 = (1 << 9), ///< Socket 1 interrupt
IK_SOCK_2 = (1 << 10), ///< Socket 2 interrupt
IK_SOCK_3 = (1 << 11), ///< Socket 3 interrupt
#if _WIZCHIP_ > 5100
IK_SOCK_4 = (1 << 12), ///< Socket 4 interrupt, No use in 5100
IK_SOCK_5 = (1 << 13), ///< Socket 5 interrupt, No use in 5100
IK_SOCK_6 = (1 << 14), ///< Socket 6 interrupt, No use in 5100
IK_SOCK_7 = (1 << 15), ///< Socket 7 interrupt, No use in 5100
#endif
#if _WIZCHIP_ > 5100
IK_SOCK_ALL = (0xFF << 8) ///< All Socket interrpt
#else
IK_SOCK_ALL = (0x0F << 8) ///< All Socket interrpt
#endif
}intr_kind;
#define PHY_CONFBY_HW 0 ///< Configured PHY operation mode by HW pin
#define PHY_CONFBY_SW 1 ///< Configured PHY operation mode by SW register
#define PHY_MODE_MANUAL 0 ///< Configured PHY operation mode with user setting.
#define PHY_MODE_AUTONEGO 1 ///< Configured PHY operation mode with auto-negotiation
#define PHY_SPEED_10 0 ///< Link Speed 10
#define PHY_SPEED_100 1 ///< Link Speed 100
#define PHY_DUPLEX_HALF 0 ///< Link Half-Duplex
#define PHY_DUPLEX_FULL 1 ///< Link Full-Duplex
#define PHY_LINK_OFF 0 ///< Link Off
#define PHY_LINK_ON 1 ///< Link On
#define PHY_POWER_NORM 0 ///< PHY power normal mode
#define PHY_POWER_DOWN 1 ///< PHY power down mode
#if _WIZCHIP_ == 5500
/**
* @ingroup DATA_TYPE
* It configures PHY configuration when CW_SET PHYCONF or CW_GET_PHYCONF in W5500,
* and it indicates the real PHY status configured by HW or SW in all WIZCHIP. \n
* Valid only in W5500.
*/
typedef struct wiz_PhyConf_t
{
uint8_t by; ///< set by @ref PHY_CONFBY_HW or @ref PHY_CONFBY_SW
uint8_t mode; ///< set by @ref PHY_MODE_MANUAL or @ref PHY_MODE_AUTONEGO
uint8_t speed; ///< set by @ref PHY_SPEED_10 or @ref PHY_SPEED_100
uint8_t duplex; ///< set by @ref PHY_DUPLEX_HALF @ref PHY_DUPLEX_FULL
//uint8_t power; ///< set by @ref PHY_POWER_NORM or @ref PHY_POWER_DOWN
//uint8_t link; ///< Valid only in CW_GET_PHYSTATUS. set by @ref PHY_LINK_ON or PHY_DUPLEX_OFF
}wiz_PhyConf;
#endif
/**
* @ingroup DATA_TYPE
* It used in setting dhcp_mode of @ref wiz_NetInfo.
*/
typedef enum
{
NETINFO_STATIC = 1, ///< Static IP configuration by manually.
NETINFO_DHCP ///< Dynamic IP configruation from a DHCP sever
}dhcp_mode;
/**
* @ingroup DATA_TYPE
* Network Information for WIZCHIP
*/
typedef struct wiz_NetInfo_t
{
uint8_t mac[6]; ///< Source Mac Address
uint8_t ip[4]; ///< Source IP Address
uint8_t sn[4]; ///< Subnet Mask
uint8_t gw[4]; ///< Gateway IP Address
uint8_t dns[4]; ///< DNS server IP Address
dhcp_mode dhcp; ///< 1 - Static, 2 - DHCP
}wiz_NetInfo;
/**
* @ingroup DATA_TYPE
* Network mode
*/
typedef enum
{
#if _WIZCHIP_ == 5500
NM_FORCEARP = (1<<1), ///< Force to APP send whenever udp data is sent. Valid only in W5500
#endif
NM_WAKEONLAN = (1<<5), ///< Wake On Lan
NM_PINGBLOCK = (1<<4), ///< Block ping-request
NM_PPPOE = (1<<3), ///< PPPoE mode
}netmode_type;
/**
* @ingroup DATA_TYPE
* Used in CN_SET_TIMEOUT or CN_GET_TIMEOUT of @ref ctlwizchip() for timeout configruation.
*/
typedef struct wiz_NetTimeout_t
{
uint8_t retry_cnt; ///< retry count
uint16_t time_100us; ///< time unit 100us
}wiz_NetTimeout;
/**
*@brief Registers call back function for critical section of I/O functions such as
*\ref WIZCHIP_READ, @ref WIZCHIP_WRITE, @ref WIZCHIP_READ_BUF and @ref WIZCHIP_WRITE_BUF.
*@param cris_en : callback function for critical section enter.
*@param cris_ex : callback function for critical section exit.
*@todo Describe @ref WIZCHIP_CRITICAL_ENTER and @ref WIZCHIP_CRITICAL_EXIT marco or register your functions.
*@note If you do not describe or register, default functions(@ref wizchip_cris_enter & @ref wizchip_cris_exit) is called.
*/
void reg_wizchip_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void));
/**
*@brief Registers call back function for WIZCHIP select & deselect.
*@param cs_sel : callback function for WIZCHIP select
*@param cs_desel : callback fucntion for WIZCHIP deselect
*@todo Describe @ref wizchip_cs_select and @ref wizchip_cs_deselect function or register your functions.
*@note If you do not describe or register, null function is called.
*/
void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void));
/**
*@brief Registers call back function for bus interface.
*@param bus_rb : callback function to read byte data using system bus
*@param bus_wb : callback function to write byte data using system bus
*@todo Describe @ref wizchip_bus_readbyte and @ref wizchip_bus_writebyte function
*or register your functions.
*@note If you do not describe or register, null function is called.
*/
void reg_wizchip_bus_cbfunc(uint8_t (*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb));
/**
*@brief Registers call back function for SPI interface.
*@param spi_rb : callback function to read byte usig SPI
*@param spi_wb : callback function to write byte usig SPI
*@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte function
*or register your functions.
*@note If you do not describe or register, null function is called.
*/
void reg_wizchip_spi_cbfunc(void (*spi_rb)(uint8_t *, uint32_t), void (*spi_wb)(const uint8_t *, uint32_t));
/**
* @ingroup extra_functions
* @brief Controls to the WIZCHIP.
* @details Resets WIZCHIP & internal PHY, Configures PHY mode, Monitor PHY(Link,Speed,Half/Full/Auto),
* controls interrupt & mask and so on.
* @param cwtype : Decides to the control type
* @param arg : arg type is dependent on cwtype.
* @return 0 : Success \n
* -1 : Fail because of invalid \ref ctlwizchip_type or unsupported \ref ctlwizchip_type in WIZCHIP
*/
int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg);
/**
* @ingroup extra_functions
* @brief Controls to network.
* @details Controls to network environment, mode, timeout and so on.
* @param cntype : Input. Decides to the control type
* @param arg : Inout. arg type is dependent on cntype.
* @return -1 : Fail because of invalid \ref ctlnetwork_type or unsupported \ref ctlnetwork_type in WIZCHIP \n
* 0 : Success
*/
int8_t ctlnetwork(ctlnetwork_type cntype, void* arg);
/*
* The following functions are implemented for internal use.
* but You can call these functions for code size reduction instead of ctlwizchip() and ctlnetwork().
*/
/**
* @ingroup extra_functions
* @brief Reset WIZCHIP by softly.
*/
void wizchip_sw_reset(void);
/**
* @ingroup extra_functions
* @brief Initializes WIZCHIP with socket buffer size
* @param txsize Socket tx buffer sizes. If null, initialized the default size 2KB.
* @param rxsize Socket rx buffer sizes. If null, initialized the default size 2KB.
* @return 0 : succcess \n
* -1 : fail. Invalid buffer size
*/
int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize);
/**
* @ingroup extra_functions
* @brief Clear Interrupt of WIZCHIP.
* @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t.
*/
void wizchip_clrinterrupt(intr_kind intr);
/**
* @ingroup extra_functions
* @brief Get Interrupt of WIZCHIP.
* @return @ref intr_kind value operated OR. It can type-cast to uint16_t.
*/
intr_kind wizchip_getinterrupt(void);
/**
* @ingroup extra_functions
* @brief Mask or Unmask Interrupt of WIZCHIP.
* @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t.
*/
void wizchip_setinterruptmask(intr_kind intr);
/**
* @ingroup extra_functions
* @brief Get Interrupt mask of WIZCHIP.
* @return : The operated OR vaule of @ref intr_kind. It can type-cast to uint16_t.
*/
intr_kind wizchip_getinterruptmask(void);
#if _WIZCHIP_ > 5100
int8_t wizphy_getphylink(void); ///< get the link status of phy in WIZCHIP. No use in W5100
int8_t wizphy_getphypmode(void); ///< get the power mode of PHY in WIZCHIP. No use in W5100
#endif
#if _WIZCHIP_ == 5500
void wizphy_reset(void); ///< Reset phy. Vailid only in W5500
/**
* @ingroup extra_functions
* @brief Set the phy information for WIZCHIP without power mode
* @param phyconf : @ref wiz_PhyConf
*/
void wizphy_setphyconf(wiz_PhyConf* phyconf);
/**
* @ingroup extra_functions
* @brief Get phy configuration information.
* @param phyconf : @ref wiz_PhyConf
*/
void wizphy_getphyconf(wiz_PhyConf* phyconf);
/**
* @ingroup extra_functions
* @brief Get phy status.
* @param phyconf : @ref wiz_PhyConf
*/
void wizphy_getphystat(wiz_PhyConf* phyconf);
/**
* @ingroup extra_functions
* @brief set the power mode of phy inside WIZCHIP. Refer to @ref PHYCFGR in W5500, @ref PHYSTATUS in W5200
* @param pmode Settig value of power down mode.
*/
int8_t wizphy_setphypmode(uint8_t pmode);
#endif
/**
* @ingroup extra_functions
* @brief Set the network information for WIZCHIP
* @param pnetinfo : @ref wizNetInfo
*/
void wizchip_setnetinfo(wiz_NetInfo* pnetinfo);
/**
* @ingroup extra_functions
* @brief Get the network information for WIZCHIP
* @param pnetinfo : @ref wizNetInfo
*/
void wizchip_getnetinfo(wiz_NetInfo* pnetinfo);
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
uint8_t *wizchip_getsubn(void);
#endif
/**
* @ingroup extra_functions
* @brief Set the network mode such WOL, PPPoE, Ping Block, and etc.
* @param pnetinfo Value of network mode. Refer to @ref netmode_type.
*/
int8_t wizchip_setnetmode(netmode_type netmode);
/**
* @ingroup extra_functions
* @brief Get the network mode such WOL, PPPoE, Ping Block, and etc.
* @return Value of network mode. Refer to @ref netmode_type.
*/
netmode_type wizchip_getnetmode(void);
/**
* @ingroup extra_functions
* @brief Set retry time value(@ref RTR) and retry count(@ref RCR).
* @details @ref RTR configures the retransmission timeout period and @ref RCR configures the number of time of retransmission.
* @param nettime @ref RTR value and @ref RCR value. Refer to @ref wiz_NetTimeout.
*/
void wizchip_settimeout(wiz_NetTimeout* nettime);
/**
* @ingroup extra_functions
* @brief Get retry time value(@ref RTR) and retry count(@ref RCR).
* @details @ref RTR configures the retransmission timeout period and @ref RCR configures the number of time of retransmission.
* @param nettime @ref RTR value and @ref RCR value. Refer to @ref wiz_NetTimeout.
*/
void wizchip_gettimeout(wiz_NetTimeout* nettime);
#endif // _WIZCHIP_CONF_H_

View file

@ -1,975 +0,0 @@
//*****************************************************************************
//
//! \file dhcp.c
//! \brief DHCP APIs implement file.
//! \details Processig DHCP protocol as DISCOVER, OFFER, REQUEST, ACK, NACK and DECLINE.
//! \version 1.1.0
//! \date 2013/11/18
//! \par Revision history
//! <2018/10/09> Modified by Nick Moore for CircuitPython
//! <2013/11/18> 1st Release
//! <2012/12/20> V1.1.0
//! 1. Optimize code
//! 2. Add reg_dhcp_cbfunc()
//! 3. Add DHCP_stop()
//! 4. Integrate check_DHCP_state() & DHCP_run() to DHCP_run()
//! 5. Don't care system endian
//! 6. Add comments
//! <2012/12/26> V1.1.1
//! 1. Modify variable declaration: dhcp_tick_1s is declared volatile for code optimization
//! \author Eric Jung & MidnightCow
//! \copyright
//!
//! Copyright (c) 2013, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
//#include "Ethernet/socket.h"
//#include "Internet/DHCP/dhcp.h"
#include "../../ethernet/socket.h"
#include "dhcp.h"
/* If you want to display debug & processing message, Define _DHCP_DEBUG_ in dhcp.h */
#ifdef _DHCP_DEBUG_
#include <stdio.h>
#endif
/* DHCP state machine. */
#define STATE_DHCP_INIT 0 ///< Initialize
#define STATE_DHCP_DISCOVER 1 ///< send DISCOVER and wait OFFER
#define STATE_DHCP_REQUEST 2 ///< send REQEUST and wait ACK or NACK
#define STATE_DHCP_LEASED 3 ///< ReceiveD ACK and IP leased
#define STATE_DHCP_REREQUEST 4 ///< send REQUEST for maintaining leased IP
#define STATE_DHCP_RELEASE 5 ///< No use
#define STATE_DHCP_STOP 6 ///< Stop processing DHCP
#define DHCP_FLAGSBROADCAST 0x8000 ///< The broadcast value of flags in @ref RIP_MSG
#define DHCP_FLAGSUNICAST 0x0000 ///< The unicast value of flags in @ref RIP_MSG
/* DHCP message OP code */
#define DHCP_BOOTREQUEST 1 ///< Request Message used in op of @ref RIP_MSG
#define DHCP_BOOTREPLY 2 ///< Reply Message used i op of @ref RIP_MSG
/* DHCP message type */
#define DHCP_DISCOVER 1 ///< DISCOVER message in OPT of @ref RIP_MSG
#define DHCP_OFFER 2 ///< OFFER message in OPT of @ref RIP_MSG
#define DHCP_REQUEST 3 ///< REQUEST message in OPT of @ref RIP_MSG
#define DHCP_DECLINE 4 ///< DECLINE message in OPT of @ref RIP_MSG
#define DHCP_ACK 5 ///< ACK message in OPT of @ref RIP_MSG
#define DHCP_NAK 6 ///< NACK message in OPT of @ref RIP_MSG
#define DHCP_RELEASE 7 ///< RELEASE message in OPT of @ref RIP_MSG. No use
#define DHCP_INFORM 8 ///< INFORM message in OPT of @ref RIP_MSG. No use
#define DHCP_HTYPE10MB 1 ///< Used in type of @ref RIP_MSG
#define DHCP_HTYPE100MB 2 ///< Used in type of @ref RIP_MSG
#define DHCP_HLENETHERNET 6 ///< Used in hlen of @ref RIP_MSG
#define DHCP_HOPS 0 ///< Used in hops of @ref RIP_MSG
#define DHCP_SECS 0 ///< Used in secs of @ref RIP_MSG
#define INFINITE_LEASETIME 0xffffffff ///< Infinite lease time
#define OPT_SIZE 312 /// Max OPT size of @ref RIP_MSG
#define RIP_MSG_SIZE (236+OPT_SIZE) /// Max size of @ref RIP_MSG
/*
* @brief DHCP option and value (cf. RFC1533)
*/
enum
{
padOption = 0,
subnetMask = 1,
timerOffset = 2,
routersOnSubnet = 3,
timeServer = 4,
nameServer = 5,
dns = 6,
logServer = 7,
cookieServer = 8,
lprServer = 9,
impressServer = 10,
resourceLocationServer = 11,
hostName = 12,
bootFileSize = 13,
meritDumpFile = 14,
domainName = 15,
swapServer = 16,
rootPath = 17,
extentionsPath = 18,
IPforwarding = 19,
nonLocalSourceRouting = 20,
policyFilter = 21,
maxDgramReasmSize = 22,
defaultIPTTL = 23,
pathMTUagingTimeout = 24,
pathMTUplateauTable = 25,
ifMTU = 26,
allSubnetsLocal = 27,
broadcastAddr = 28,
performMaskDiscovery = 29,
maskSupplier = 30,
performRouterDiscovery = 31,
routerSolicitationAddr = 32,
staticRoute = 33,
trailerEncapsulation = 34,
arpCacheTimeout = 35,
ethernetEncapsulation = 36,
tcpDefaultTTL = 37,
tcpKeepaliveInterval = 38,
tcpKeepaliveGarbage = 39,
nisDomainName = 40,
nisServers = 41,
ntpServers = 42,
vendorSpecificInfo = 43,
netBIOSnameServer = 44,
netBIOSdgramDistServer = 45,
netBIOSnodeType = 46,
netBIOSscope = 47,
xFontServer = 48,
xDisplayManager = 49,
dhcpRequestedIPaddr = 50,
dhcpIPaddrLeaseTime = 51,
dhcpOptionOverload = 52,
dhcpMessageType = 53,
dhcpServerIdentifier = 54,
dhcpParamRequest = 55,
dhcpMsg = 56,
dhcpMaxMsgSize = 57,
dhcpT1value = 58,
dhcpT2value = 59,
dhcpClassIdentifier = 60,
dhcpClientIdentifier = 61,
endOption = 255
};
/*
* @brief DHCP message format
*/
typedef struct {
uint8_t op; ///< @ref DHCP_BOOTREQUEST or @ref DHCP_BOOTREPLY
uint8_t htype; ///< @ref DHCP_HTYPE10MB or @ref DHCP_HTYPE100MB
uint8_t hlen; ///< @ref DHCP_HLENETHERNET
uint8_t hops; ///< @ref DHCP_HOPS
uint32_t xid; ///< @ref DHCP_XID This increase one every DHCP transaction.
uint16_t secs; ///< @ref DHCP_SECS
uint16_t flags; ///< @ref DHCP_FLAGSBROADCAST or @ref DHCP_FLAGSUNICAST
uint8_t ciaddr[4]; ///< @ref Request IP to DHCP sever
uint8_t yiaddr[4]; ///< @ref Offered IP from DHCP server
uint8_t siaddr[4]; ///< No use
uint8_t giaddr[4]; ///< No use
uint8_t chaddr[16]; ///< DHCP client 6bytes MAC address. Others is filled to zero
uint8_t sname[64]; ///< No use
uint8_t file[128]; ///< No use
uint8_t OPT[OPT_SIZE]; ///< Option
} RIP_MSG;
uint8_t DHCP_SOCKET; // Socket number for DHCP
uint8_t DHCP_SIP[4]; // DHCP Server IP address
// Network information from DHCP Server
uint8_t OLD_allocated_ip[4] = {0, }; // Previous IP address
uint8_t DHCP_allocated_ip[4] = {0, }; // IP address from DHCP
uint8_t DHCP_allocated_gw[4] = {0, }; // Gateway address from DHCP
uint8_t DHCP_allocated_sn[4] = {0, }; // Subnet mask from DHCP
uint8_t DHCP_allocated_dns[4] = {0, }; // DNS address from DHCP
int8_t dhcp_state = STATE_DHCP_INIT; // DHCP state
int8_t dhcp_retry_count = 0;
uint32_t dhcp_lease_time = INFINITE_LEASETIME;
volatile uint32_t dhcp_tick_1s = 0; // unit 1 second
uint32_t dhcp_tick_next = DHCP_WAIT_TIME ;
uint32_t DHCP_XID; // Any number
RIP_MSG* pDHCPMSG; // Buffer pointer for DHCP processing
uint8_t HOST_NAME[] = DCHP_HOST_NAME;
uint8_t DHCP_CHADDR[6]; // DHCP Client MAC address.
/* The default callback function */
void default_ip_assign(void);
void default_ip_update(void);
void default_ip_conflict(void);
/* Callback handler */
void (*dhcp_ip_assign)(void) = default_ip_assign; /* handler to be called when the IP address from DHCP server is first assigned */
void (*dhcp_ip_update)(void) = default_ip_update; /* handler to be called when the IP address from DHCP server is updated */
void (*dhcp_ip_conflict)(void) = default_ip_conflict; /* handler to be called when the IP address from DHCP server is conflict */
void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void));
/* send DISCOVER message to DHCP server */
void send_DHCP_DISCOVER(void);
/* send REQEUST message to DHCP server */
void send_DHCP_REQUEST(void);
/* send DECLINE message to DHCP server */
void send_DHCP_DECLINE(void);
/* IP conflict check by sending ARP-request to leased IP and wait ARP-response. */
int8_t check_DHCP_leasedIP(void);
/* check the timeout in DHCP process */
uint8_t check_DHCP_timeout(void);
/* Intialize to timeout process. */
void reset_DHCP_timeout(void);
/* Parse message as OFFER and ACK and NACK from DHCP server.*/
int8_t parseDHCPCMSG(void);
/* The default handler of ip assign first */
void default_ip_assign(void)
{
setSIPR(DHCP_allocated_ip);
setSUBR(DHCP_allocated_sn);
setGAR (DHCP_allocated_gw);
}
/* The default handler of ip changed */
void default_ip_update(void)
{
/* WIZchip Software Reset */
setMR(MR_RST);
getMR(); // for delay
default_ip_assign();
setSHAR(DHCP_CHADDR);
}
/* The default handler of ip changed */
void default_ip_conflict(void)
{
// WIZchip Software Reset
setMR(MR_RST);
getMR(); // for delay
setSHAR(DHCP_CHADDR);
}
/* register the call back func. */
void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void))
{
dhcp_ip_assign = default_ip_assign;
dhcp_ip_update = default_ip_update;
dhcp_ip_conflict = default_ip_conflict;
if(ip_assign) dhcp_ip_assign = ip_assign;
if(ip_update) dhcp_ip_update = ip_update;
if(ip_conflict) dhcp_ip_conflict = ip_conflict;
}
/* make the common DHCP message */
void makeDHCPMSG(void)
{
uint8_t bk_mac[6];
uint8_t* ptmp;
uint8_t i;
getSHAR(bk_mac);
pDHCPMSG->op = DHCP_BOOTREQUEST;
pDHCPMSG->htype = DHCP_HTYPE10MB;
pDHCPMSG->hlen = DHCP_HLENETHERNET;
pDHCPMSG->hops = DHCP_HOPS;
ptmp = (uint8_t*)(&pDHCPMSG->xid);
*(ptmp+0) = (uint8_t)((DHCP_XID & 0xFF000000) >> 24);
*(ptmp+1) = (uint8_t)((DHCP_XID & 0x00FF0000) >> 16);
*(ptmp+2) = (uint8_t)((DHCP_XID & 0x0000FF00) >> 8);
*(ptmp+3) = (uint8_t)((DHCP_XID & 0x000000FF) >> 0);
pDHCPMSG->secs = DHCP_SECS;
ptmp = (uint8_t*)(&pDHCPMSG->flags);
*(ptmp+0) = (uint8_t)((DHCP_FLAGSBROADCAST & 0xFF00) >> 8);
*(ptmp+1) = (uint8_t)((DHCP_FLAGSBROADCAST & 0x00FF) >> 0);
pDHCPMSG->ciaddr[0] = 0;
pDHCPMSG->ciaddr[1] = 0;
pDHCPMSG->ciaddr[2] = 0;
pDHCPMSG->ciaddr[3] = 0;
pDHCPMSG->yiaddr[0] = 0;
pDHCPMSG->yiaddr[1] = 0;
pDHCPMSG->yiaddr[2] = 0;
pDHCPMSG->yiaddr[3] = 0;
pDHCPMSG->siaddr[0] = 0;
pDHCPMSG->siaddr[1] = 0;
pDHCPMSG->siaddr[2] = 0;
pDHCPMSG->siaddr[3] = 0;
pDHCPMSG->giaddr[0] = 0;
pDHCPMSG->giaddr[1] = 0;
pDHCPMSG->giaddr[2] = 0;
pDHCPMSG->giaddr[3] = 0;
pDHCPMSG->chaddr[0] = DHCP_CHADDR[0];
pDHCPMSG->chaddr[1] = DHCP_CHADDR[1];
pDHCPMSG->chaddr[2] = DHCP_CHADDR[2];
pDHCPMSG->chaddr[3] = DHCP_CHADDR[3];
pDHCPMSG->chaddr[4] = DHCP_CHADDR[4];
pDHCPMSG->chaddr[5] = DHCP_CHADDR[5];
for (i = 6; i < 16; i++) pDHCPMSG->chaddr[i] = 0;
for (i = 0; i < 64; i++) pDHCPMSG->sname[i] = 0;
for (i = 0; i < 128; i++) pDHCPMSG->file[i] = 0;
// MAGIC_COOKIE
pDHCPMSG->OPT[0] = (uint8_t)((MAGIC_COOKIE & 0xFF000000) >> 24);
pDHCPMSG->OPT[1] = (uint8_t)((MAGIC_COOKIE & 0x00FF0000) >> 16);
pDHCPMSG->OPT[2] = (uint8_t)((MAGIC_COOKIE & 0x0000FF00) >> 8);
pDHCPMSG->OPT[3] = (uint8_t) (MAGIC_COOKIE & 0x000000FF) >> 0;
}
/* SEND DHCP DISCOVER */
void send_DHCP_DISCOVER(void)
{
uint16_t i;
uint8_t ip[4];
uint16_t k = 0;
makeDHCPMSG();
k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG()
// Option Request Param
pDHCPMSG->OPT[k++] = dhcpMessageType;
pDHCPMSG->OPT[k++] = 0x01;
pDHCPMSG->OPT[k++] = DHCP_DISCOVER;
// Client identifier
pDHCPMSG->OPT[k++] = dhcpClientIdentifier;
pDHCPMSG->OPT[k++] = 0x07;
pDHCPMSG->OPT[k++] = 0x01;
pDHCPMSG->OPT[k++] = DHCP_CHADDR[0];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[1];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[2];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
// host name
pDHCPMSG->OPT[k++] = hostName;
pDHCPMSG->OPT[k++] = 0; // fill zero length of hostname
for(i = 0 ; HOST_NAME[i] != 0; i++)
pDHCPMSG->OPT[k++] = HOST_NAME[i];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
pDHCPMSG->OPT[k - (i+3+1)] = i+3; // length of hostname
pDHCPMSG->OPT[k++] = dhcpParamRequest;
pDHCPMSG->OPT[k++] = 0x06; // length of request
pDHCPMSG->OPT[k++] = subnetMask;
pDHCPMSG->OPT[k++] = routersOnSubnet;
pDHCPMSG->OPT[k++] = dns;
pDHCPMSG->OPT[k++] = domainName;
pDHCPMSG->OPT[k++] = dhcpT1value;
pDHCPMSG->OPT[k++] = dhcpT2value;
pDHCPMSG->OPT[k++] = endOption;
for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0;
// send broadcasting packet
ip[0] = 255;
ip[1] = 255;
ip[2] = 255;
ip[3] = 255;
#ifdef _DHCP_DEBUG_
printf("> Send DHCP_DISCOVER\r\n");
#endif
WIZCHIP_EXPORT(sendto)(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT);
}
/* SEND DHCP REQUEST */
void send_DHCP_REQUEST(void)
{
int i;
uint8_t ip[4];
uint16_t k = 0;
makeDHCPMSG();
if(dhcp_state == STATE_DHCP_LEASED || dhcp_state == STATE_DHCP_REREQUEST)
{
*((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8);
*((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF);
pDHCPMSG->ciaddr[0] = DHCP_allocated_ip[0];
pDHCPMSG->ciaddr[1] = DHCP_allocated_ip[1];
pDHCPMSG->ciaddr[2] = DHCP_allocated_ip[2];
pDHCPMSG->ciaddr[3] = DHCP_allocated_ip[3];
ip[0] = DHCP_SIP[0];
ip[1] = DHCP_SIP[1];
ip[2] = DHCP_SIP[2];
ip[3] = DHCP_SIP[3];
}
else
{
ip[0] = 255;
ip[1] = 255;
ip[2] = 255;
ip[3] = 255;
}
k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG()
// Option Request Param.
pDHCPMSG->OPT[k++] = dhcpMessageType;
pDHCPMSG->OPT[k++] = 0x01;
pDHCPMSG->OPT[k++] = DHCP_REQUEST;
pDHCPMSG->OPT[k++] = dhcpClientIdentifier;
pDHCPMSG->OPT[k++] = 0x07;
pDHCPMSG->OPT[k++] = 0x01;
pDHCPMSG->OPT[k++] = DHCP_CHADDR[0];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[1];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[2];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
if(ip[3] == 255) // if(dchp_state == STATE_DHCP_LEASED || dchp_state == DHCP_REREQUEST_STATE)
{
pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr;
pDHCPMSG->OPT[k++] = 0x04;
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0];
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1];
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2];
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3];
pDHCPMSG->OPT[k++] = dhcpServerIdentifier;
pDHCPMSG->OPT[k++] = 0x04;
pDHCPMSG->OPT[k++] = DHCP_SIP[0];
pDHCPMSG->OPT[k++] = DHCP_SIP[1];
pDHCPMSG->OPT[k++] = DHCP_SIP[2];
pDHCPMSG->OPT[k++] = DHCP_SIP[3];
}
// host name
pDHCPMSG->OPT[k++] = hostName;
pDHCPMSG->OPT[k++] = 0; // length of hostname
for(i = 0 ; HOST_NAME[i] != 0; i++)
pDHCPMSG->OPT[k++] = HOST_NAME[i];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
pDHCPMSG->OPT[k - (i+3+1)] = i+3; // length of hostname
pDHCPMSG->OPT[k++] = dhcpParamRequest;
pDHCPMSG->OPT[k++] = 0x08;
pDHCPMSG->OPT[k++] = subnetMask;
pDHCPMSG->OPT[k++] = routersOnSubnet;
pDHCPMSG->OPT[k++] = dns;
pDHCPMSG->OPT[k++] = domainName;
pDHCPMSG->OPT[k++] = dhcpT1value;
pDHCPMSG->OPT[k++] = dhcpT2value;
pDHCPMSG->OPT[k++] = performRouterDiscovery;
pDHCPMSG->OPT[k++] = staticRoute;
pDHCPMSG->OPT[k++] = endOption;
for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0;
#ifdef _DHCP_DEBUG_
printf("> Send DHCP_REQUEST\r\n");
#endif
WIZCHIP_EXPORT(sendto)(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT);
}
/* SEND DHCP DHCPDECLINE */
void send_DHCP_DECLINE(void)
{
int i;
uint8_t ip[4];
uint16_t k = 0;
makeDHCPMSG();
k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG()
*((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8);
*((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF);
// Option Request Param.
pDHCPMSG->OPT[k++] = dhcpMessageType;
pDHCPMSG->OPT[k++] = 0x01;
pDHCPMSG->OPT[k++] = DHCP_DECLINE;
pDHCPMSG->OPT[k++] = dhcpClientIdentifier;
pDHCPMSG->OPT[k++] = 0x07;
pDHCPMSG->OPT[k++] = 0x01;
pDHCPMSG->OPT[k++] = DHCP_CHADDR[0];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[1];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[2];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr;
pDHCPMSG->OPT[k++] = 0x04;
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0];
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1];
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2];
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3];
pDHCPMSG->OPT[k++] = dhcpServerIdentifier;
pDHCPMSG->OPT[k++] = 0x04;
pDHCPMSG->OPT[k++] = DHCP_SIP[0];
pDHCPMSG->OPT[k++] = DHCP_SIP[1];
pDHCPMSG->OPT[k++] = DHCP_SIP[2];
pDHCPMSG->OPT[k++] = DHCP_SIP[3];
pDHCPMSG->OPT[k++] = endOption;
for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0;
//send broadcasting packet
ip[0] = 0xFF;
ip[1] = 0xFF;
ip[2] = 0xFF;
ip[3] = 0xFF;
#ifdef _DHCP_DEBUG_
printf("\r\n> Send DHCP_DECLINE\r\n");
#endif
WIZCHIP_EXPORT(sendto)(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT);
}
/* PARSE REPLY pDHCPMSG */
int8_t parseDHCPMSG(void)
{
uint8_t svr_addr[6];
uint16_t svr_port;
uint16_t len;
uint8_t * p;
uint8_t * e;
uint8_t type = 0;
uint8_t opt_len;
if((len = getSn_RX_RSR(DHCP_SOCKET)) > 0)
{
len = WIZCHIP_EXPORT(recvfrom)(DHCP_SOCKET, (uint8_t *)pDHCPMSG, len, svr_addr, &svr_port);
#ifdef _DHCP_DEBUG_
printf("DHCP message : %d.%d.%d.%d(%d) %d received. \r\n",svr_addr[0],svr_addr[1],svr_addr[2], svr_addr[3],svr_port, len);
#endif
}
else return 0;
if (svr_port == DHCP_SERVER_PORT) {
// compare mac address
if ( (pDHCPMSG->chaddr[0] != DHCP_CHADDR[0]) || (pDHCPMSG->chaddr[1] != DHCP_CHADDR[1]) ||
(pDHCPMSG->chaddr[2] != DHCP_CHADDR[2]) || (pDHCPMSG->chaddr[3] != DHCP_CHADDR[3]) ||
(pDHCPMSG->chaddr[4] != DHCP_CHADDR[4]) || (pDHCPMSG->chaddr[5] != DHCP_CHADDR[5]) )
return 0;
type = 0;
p = (uint8_t *)(&pDHCPMSG->op);
p = p + 240; // 240 = sizeof(RIP_MSG) + MAGIC_COOKIE size in RIP_MSG.opt - sizeof(RIP_MSG.opt)
e = p + (len - 240);
while ( p < e ) {
switch ( *p ) {
case endOption :
p = e; // for break while(p < e)
break;
case padOption :
p++;
break;
case dhcpMessageType :
p++;
p++;
type = *p++;
break;
case subnetMask :
p++;
p++;
DHCP_allocated_sn[0] = *p++;
DHCP_allocated_sn[1] = *p++;
DHCP_allocated_sn[2] = *p++;
DHCP_allocated_sn[3] = *p++;
break;
case routersOnSubnet :
p++;
opt_len = *p++;
DHCP_allocated_gw[0] = *p++;
DHCP_allocated_gw[1] = *p++;
DHCP_allocated_gw[2] = *p++;
DHCP_allocated_gw[3] = *p++;
p = p + (opt_len - 4);
break;
case dns :
p++;
opt_len = *p++;
DHCP_allocated_dns[0] = *p++;
DHCP_allocated_dns[1] = *p++;
DHCP_allocated_dns[2] = *p++;
DHCP_allocated_dns[3] = *p++;
p = p + (opt_len - 4);
break;
case dhcpIPaddrLeaseTime :
p++;
opt_len = *p++;
dhcp_lease_time = *p++;
dhcp_lease_time = (dhcp_lease_time << 8) + *p++;
dhcp_lease_time = (dhcp_lease_time << 8) + *p++;
dhcp_lease_time = (dhcp_lease_time << 8) + *p++;
#ifdef _DHCP_DEBUG_
dhcp_lease_time = 10;
#endif
break;
case dhcpServerIdentifier :
p++;
opt_len = *p++;
DHCP_SIP[0] = *p++;
DHCP_SIP[1] = *p++;
DHCP_SIP[2] = *p++;
DHCP_SIP[3] = *p++;
break;
default :
p++;
opt_len = *p++;
p += opt_len;
break;
} // switch
} // while
} // if
return type;
}
uint8_t DHCP_run(void)
{
uint8_t type;
uint8_t ret;
if(dhcp_state == STATE_DHCP_STOP) return DHCP_STOPPED;
if(getSn_SR(DHCP_SOCKET) != SOCK_UDP)
WIZCHIP_EXPORT(socket)(DHCP_SOCKET, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00);
ret = DHCP_RUNNING;
type = parseDHCPMSG();
switch ( dhcp_state ) {
case STATE_DHCP_INIT :
DHCP_allocated_ip[0] = 0;
DHCP_allocated_ip[1] = 0;
DHCP_allocated_ip[2] = 0;
DHCP_allocated_ip[3] = 0;
send_DHCP_DISCOVER();
dhcp_state = STATE_DHCP_DISCOVER;
break;
case STATE_DHCP_DISCOVER :
if (type == DHCP_OFFER){
#ifdef _DHCP_DEBUG_
printf("> Receive DHCP_OFFER\r\n");
#endif
DHCP_allocated_ip[0] = pDHCPMSG->yiaddr[0];
DHCP_allocated_ip[1] = pDHCPMSG->yiaddr[1];
DHCP_allocated_ip[2] = pDHCPMSG->yiaddr[2];
DHCP_allocated_ip[3] = pDHCPMSG->yiaddr[3];
send_DHCP_REQUEST();
dhcp_state = STATE_DHCP_REQUEST;
} else ret = check_DHCP_timeout();
break;
case STATE_DHCP_REQUEST :
if (type == DHCP_ACK) {
#ifdef _DHCP_DEBUG_
printf("> Receive DHCP_ACK\r\n");
#endif
if (check_DHCP_leasedIP()) {
// Network info assignment from DHCP
dhcp_ip_assign();
reset_DHCP_timeout();
dhcp_state = STATE_DHCP_LEASED;
} else {
// IP address conflict occurred
reset_DHCP_timeout();
dhcp_ip_conflict();
dhcp_state = STATE_DHCP_INIT;
}
} else if (type == DHCP_NAK) {
#ifdef _DHCP_DEBUG_
printf("> Receive DHCP_NACK\r\n");
#endif
reset_DHCP_timeout();
dhcp_state = STATE_DHCP_DISCOVER;
} else ret = check_DHCP_timeout();
break;
case STATE_DHCP_LEASED :
ret = DHCP_IP_LEASED;
if ((dhcp_lease_time != INFINITE_LEASETIME) && ((dhcp_lease_time/2) < dhcp_tick_1s)) {
#ifdef _DHCP_DEBUG_
printf("> Maintains the IP address \r\n");
#endif
type = 0;
OLD_allocated_ip[0] = DHCP_allocated_ip[0];
OLD_allocated_ip[1] = DHCP_allocated_ip[1];
OLD_allocated_ip[2] = DHCP_allocated_ip[2];
OLD_allocated_ip[3] = DHCP_allocated_ip[3];
DHCP_XID++;
send_DHCP_REQUEST();
reset_DHCP_timeout();
dhcp_state = STATE_DHCP_REREQUEST;
}
break;
case STATE_DHCP_REREQUEST :
ret = DHCP_IP_LEASED;
if (type == DHCP_ACK) {
dhcp_retry_count = 0;
if (OLD_allocated_ip[0] != DHCP_allocated_ip[0] ||
OLD_allocated_ip[1] != DHCP_allocated_ip[1] ||
OLD_allocated_ip[2] != DHCP_allocated_ip[2] ||
OLD_allocated_ip[3] != DHCP_allocated_ip[3])
{
ret = DHCP_IP_CHANGED;
dhcp_ip_update();
#ifdef _DHCP_DEBUG_
printf(">IP changed.\r\n");
#endif
}
#ifdef _DHCP_DEBUG_
else printf(">IP is continued.\r\n");
#endif
reset_DHCP_timeout();
dhcp_state = STATE_DHCP_LEASED;
} else if (type == DHCP_NAK) {
#ifdef _DHCP_DEBUG_
printf("> Receive DHCP_NACK, Failed to maintain ip\r\n");
#endif
reset_DHCP_timeout();
dhcp_state = STATE_DHCP_DISCOVER;
} else ret = check_DHCP_timeout();
break;
default :
break;
}
return ret;
}
void DHCP_stop(void)
{
WIZCHIP_EXPORT(close)(DHCP_SOCKET);
dhcp_state = STATE_DHCP_STOP;
}
uint8_t check_DHCP_timeout(void)
{
uint8_t ret = DHCP_RUNNING;
if (dhcp_retry_count < MAX_DHCP_RETRY) {
if (dhcp_tick_next < dhcp_tick_1s) {
switch ( dhcp_state ) {
case STATE_DHCP_DISCOVER :
// printf("<<timeout>> state : STATE_DHCP_DISCOVER\r\n");
send_DHCP_DISCOVER();
break;
case STATE_DHCP_REQUEST :
// printf("<<timeout>> state : STATE_DHCP_REQUEST\r\n");
send_DHCP_REQUEST();
break;
case STATE_DHCP_REREQUEST :
// printf("<<timeout>> state : STATE_DHCP_REREQUEST\r\n");
send_DHCP_REQUEST();
break;
default :
break;
}
dhcp_tick_1s = 0;
dhcp_tick_next = dhcp_tick_1s + DHCP_WAIT_TIME;
dhcp_retry_count++;
}
} else { // timeout occurred
switch(dhcp_state) {
case STATE_DHCP_DISCOVER:
dhcp_state = STATE_DHCP_INIT;
ret = DHCP_FAILED;
break;
case STATE_DHCP_REQUEST:
case STATE_DHCP_REREQUEST:
send_DHCP_DISCOVER();
dhcp_state = STATE_DHCP_DISCOVER;
break;
default :
break;
}
reset_DHCP_timeout();
}
return ret;
}
int8_t check_DHCP_leasedIP(void)
{
uint8_t tmp;
int32_t ret;
//WIZchip RCR value changed for ARP Timeout count control
tmp = getRCR();
setRCR(0x03);
// IP conflict detection : ARP request - ARP reply
// Broadcasting ARP Request for check the IP conflict using UDP sendto() function
ret = WIZCHIP_EXPORT(sendto)(DHCP_SOCKET, (uint8_t *)"CHECK_IP_CONFLICT", 17, DHCP_allocated_ip, 5000);
// RCR value restore
setRCR(tmp);
if(ret == SOCKERR_TIMEOUT) {
// UDP send Timeout occurred : allocated IP address is unique, DHCP Success
#ifdef _DHCP_DEBUG_
printf("\r\n> Check leased IP - OK\r\n");
#endif
return 1;
} else {
// Received ARP reply or etc : IP address conflict occur, DHCP Failed
send_DHCP_DECLINE();
ret = dhcp_tick_1s;
while((dhcp_tick_1s - ret) < 2) ; // wait for 1s over; wait to complete to send DECLINE message;
return 0;
}
}
void DHCP_init(uint8_t s, DHCP_INIT_BUFFER_TYPE* buf)
{
uint8_t zeroip[4] = {0,0,0,0};
getSHAR(DHCP_CHADDR);
if((DHCP_CHADDR[0] | DHCP_CHADDR[1] | DHCP_CHADDR[2] | DHCP_CHADDR[3] | DHCP_CHADDR[4] | DHCP_CHADDR[5]) == 0x00)
{
// assign temporary mac address, you should be set SHAR before call this function.
DHCP_CHADDR[0] = 0x00;
DHCP_CHADDR[1] = 0x08;
DHCP_CHADDR[2] = 0xdc;
DHCP_CHADDR[3] = 0x00;
DHCP_CHADDR[4] = 0x00;
DHCP_CHADDR[5] = 0x00;
setSHAR(DHCP_CHADDR);
}
DHCP_SOCKET = s; // SOCK_DHCP
pDHCPMSG = (RIP_MSG*)buf;
DHCP_XID = 0x12345678;
// WIZchip Netinfo Clear
setSIPR(zeroip);
setSIPR(zeroip);
setGAR(zeroip);
reset_DHCP_timeout();
dhcp_state = STATE_DHCP_INIT;
}
/* Rset the DHCP timeout count and retry count. */
void reset_DHCP_timeout(void)
{
dhcp_tick_1s = 0;
dhcp_tick_next = DHCP_WAIT_TIME;
dhcp_retry_count = 0;
}
void DHCP_time_handler(void)
{
dhcp_tick_1s++;
}
void getIPfromDHCP(uint8_t* ip)
{
ip[0] = DHCP_allocated_ip[0];
ip[1] = DHCP_allocated_ip[1];
ip[2] = DHCP_allocated_ip[2];
ip[3] = DHCP_allocated_ip[3];
}
void getGWfromDHCP(uint8_t* ip)
{
ip[0] =DHCP_allocated_gw[0];
ip[1] =DHCP_allocated_gw[1];
ip[2] =DHCP_allocated_gw[2];
ip[3] =DHCP_allocated_gw[3];
}
void getSNfromDHCP(uint8_t* ip)
{
ip[0] = DHCP_allocated_sn[0];
ip[1] = DHCP_allocated_sn[1];
ip[2] = DHCP_allocated_sn[2];
ip[3] = DHCP_allocated_sn[3];
}
void getDNSfromDHCP(uint8_t* ip)
{
ip[0] = DHCP_allocated_dns[0];
ip[1] = DHCP_allocated_dns[1];
ip[2] = DHCP_allocated_dns[2];
ip[3] = DHCP_allocated_dns[3];
}
uint32_t getDHCPLeasetime(void)
{
return dhcp_lease_time;
}

View file

@ -1,152 +0,0 @@
//*****************************************************************************
//
//! \file dhcp.h
//! \brief DHCP APIs Header file.
//! \details Processig DHCP protocol as DISCOVER, OFFER, REQUEST, ACK, NACK and DECLINE.
//! \version 1.1.0
//! \date 2013/11/18
//! \par Revision history
//! <2013/11/18> 1st Release
//! <2012/12/20> V1.1.0
//! 1. Move unreferenced DEFINE to dhcp.c
//! <2012/12/26> V1.1.1
//! \author Eric Jung & MidnightCow
//! \copyright
//!
//! Copyright (c) 2013, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
#ifndef _DHCP_H_
#define _DHCP_H_
/*
* @brief
* @details If you want to display debug & processing message, Define _DHCP_DEBUG_
* @note If defined, it depends on <stdio.h>
*/
//#define _DHCP_DEBUG_
/* Retry to processing DHCP */
#define MAX_DHCP_RETRY 2 ///< Maximum retry count
#define DHCP_WAIT_TIME 3 ///< Wait Time 3s (was 10s)
/* UDP port numbers for DHCP */
#define DHCP_SERVER_PORT 67 ///< DHCP server port number
#define DHCP_CLIENT_PORT 68 ///< DHCP client port number
#define MAGIC_COOKIE 0x63825363 ///< Any number. You can be modified it any number
#define DCHP_HOST_NAME "WIZnet\0"
/*
* @brief return value of @ref DHCP_run()
*/
enum
{
DHCP_FAILED = 0, ///< Processing Fail
DHCP_RUNNING, ///< Processing DHCP protocol
DHCP_IP_ASSIGN, ///< First Occupy IP from DHPC server (if cbfunc == null, act as default default_ip_assign)
DHCP_IP_CHANGED, ///< Change IP address by new IP address from DHCP (if cbfunc == null, act as default default_ip_update)
DHCP_IP_LEASED, ///< Stand by
DHCP_STOPPED ///< Stop processing DHCP protocol
};
#define DHCP_INIT_BUFFER_TYPE uint32_t
#define DHCP_INIT_BUFFER_SIZE (137)
/*
* @brief DHCP client initialization (outside of the main loop)
* @param s - socket number
* @param buf - buffer for processing DHCP message
*/
void DHCP_init(uint8_t s, DHCP_INIT_BUFFER_TYPE* buf);
/*
* @brief DHCP 1s Tick Timer handler
* @note SHOULD BE register to your system 1s Tick timer handler
*/
void DHCP_time_handler(void);
/*
* @brief Register call back function
* @param ip_assign - callback func when IP is assigned from DHCP server first
* @param ip_update - callback func when IP is changed
* @prarm ip_conflict - callback func when the assigned IP is conflict with others.
*/
void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void));
/*
* @brief DHCP client in the main loop
* @return The value is as the follow \n
* @ref DHCP_FAILED \n
* @ref DHCP_RUNNING \n
* @ref DHCP_IP_ASSIGN \n
* @ref DHCP_IP_CHANGED \n
* @ref DHCP_IP_LEASED \n
* @ref DHCP_STOPPED \n
*
* @note This function is always called by you main task.
*/
uint8_t DHCP_run(void);
/*
* @brief Stop DHCP processing
* @note If you want to restart. call DHCP_init() and DHCP_run()
*/
void DHCP_stop(void);
/* Get Network information assigned from DHCP server */
/*
* @brief Get IP address
* @param ip - IP address to be returned
*/
void getIPfromDHCP(uint8_t* ip);
/*
* @brief Get Gateway address
* @param ip - Gateway address to be returned
*/
void getGWfromDHCP(uint8_t* ip);
/*
* @brief Get Subnet mask value
* @param ip - Subnet mask to be returned
*/
void getSNfromDHCP(uint8_t* ip);
/*
* @brief Get DNS address
* @param ip - DNS address to be returned
*/
void getDNSfromDHCP(uint8_t* ip);
/*
* @brief Get the leased time by DHCP sever
* @return unit 1s
*/
uint32_t getDHCPLeasetime(void);
#endif /* _DHCP_H_ */

View file

@ -1,572 +0,0 @@
//*****************************************************************************
//
//! \file dns.c
//! \brief DNS APIs Implement file.
//! \details Send DNS query & Receive DNS reponse. \n
//! It depends on stdlib.h & string.h in ansi-c library
//! \version 1.1.0
//! \date 2013/11/18
//! \par Revision history
//! <2013/10/21> 1st Release
//! <2013/12/20> V1.1.0
//! 1. Remove secondary DNS server in DNS_run
//! If 1st DNS_run failed, call DNS_run with 2nd DNS again
//! 2. DNS_timerHandler -> DNS_time_handler
//! 3. Remove the unused define
//! 4. Integrated dns.h dns.c & dns_parse.h dns_parse.c into dns.h & dns.c
//! <2013/12/20> V1.1.0
//! <2018/10/04> Modified HAL_GetTick for use with CircuitPython by Nick Moore
//!
//! \author Eric Jung & MidnightCow
//! \copyright
//!
//! Copyright (c) 2013, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
#include <string.h>
#include <stdlib.h>
#include "supervisor/shared/tick.h"
//#include "Ethernet/socket.h"
//#include "Internet/DNS/dns.h"
#include "../../ethernet/socket.h"
#include "dns.h"
#ifdef _DNS_DEBUG_
#include <stdio.h>
#endif
#define INITRTT 2000L /* Initial smoothed response time */
#define MAXCNAME (MAX_DOMAIN_NAME + (MAX_DOMAIN_NAME>>1)) /* Maximum amount of cname recursion */
#define TYPE_A 1 /* Host address */
#define TYPE_NS 2 /* Name server */
#define TYPE_MD 3 /* Mail destination (obsolete) */
#define TYPE_MF 4 /* Mail forwarder (obsolete) */
#define TYPE_CNAME 5 /* Canonical name */
#define TYPE_SOA 6 /* Start of Authority */
#define TYPE_MB 7 /* Mailbox name (experimental) */
#define TYPE_MG 8 /* Mail group member (experimental) */
#define TYPE_MR 9 /* Mail rename name (experimental) */
#define TYPE_NULL 10 /* Null (experimental) */
#define TYPE_WKS 11 /* Well-known sockets */
#define TYPE_PTR 12 /* Pointer record */
#define TYPE_HINFO 13 /* Host information */
#define TYPE_MINFO 14 /* Mailbox information (experimental)*/
#define TYPE_MX 15 /* Mail exchanger */
#define TYPE_TXT 16 /* Text strings */
#define TYPE_ANY 255 /* Matches any type */
#define CLASS_IN 1 /* The ARPA Internet */
/* Round trip timing parameters */
#define AGAIN 8 /* Average RTT gain = 1/8 */
#define LAGAIN 3 /* Log2(AGAIN) */
#define DGAIN 4 /* Mean deviation gain = 1/4 */
#define LDGAIN 2 /* log2(DGAIN) */
/* Header for all domain messages */
struct dhdr
{
uint16_t id; /* Identification */
uint8_t qr; /* Query/Response */
#define QUERY 0
#define RESPONSE 1
uint8_t opcode;
#define IQUERY 1
uint8_t aa; /* Authoratative answer */
uint8_t tc; /* Truncation */
uint8_t rd; /* Recursion desired */
uint8_t ra; /* Recursion available */
uint8_t rcode; /* Response code */
#define NO_ERROR 0
#define FORMAT_ERROR 1
#define SERVER_FAIL 2
#define NAME_ERROR 3
#define NOT_IMPL 4
#define REFUSED 5
uint16_t qdcount; /* Question count */
uint16_t ancount; /* Answer count */
uint16_t nscount; /* Authority (name server) count */
uint16_t arcount; /* Additional record count */
};
uint8_t* pDNSMSG; // DNS message buffer
uint8_t DNS_SOCKET; // SOCKET number for DNS
uint16_t DNS_MSGID; // DNS message ID
uint32_t HAL_GetTick(void) {
return supervisor_ticks_ms32();
}
uint32_t hal_sys_tick;
/* converts uint16_t from network buffer to a host byte order integer. */
uint16_t get16(uint8_t * s)
{
uint16_t i;
i = *s++ << 8;
i = i + *s;
return i;
}
/* copies uint16_t to the network buffer with network byte order. */
uint8_t * put16(uint8_t * s, uint16_t i)
{
*s++ = i >> 8;
*s++ = i;
return s;
}
/*
* CONVERT A DOMAIN NAME TO THE HUMAN-READABLE FORM
*
* Description : This function converts a compressed domain name to the human-readable form
* Arguments : msg - is a pointer to the reply message
* compressed - is a pointer to the domain name in reply message.
* buf - is a pointer to the buffer for the human-readable form name.
* len - is the MAX. size of buffer.
* Returns : the length of compressed message
*/
int parse_name(uint8_t * msg, uint8_t * compressed, char * buf, int16_t len)
{
uint16_t slen; /* Length of current segment */
uint8_t * cp;
int clen = 0; /* Total length of compressed name */
int indirect = 0; /* Set if indirection encountered */
int nseg = 0; /* Total number of segments in name */
cp = compressed;
for (;;)
{
slen = *cp++; /* Length of this segment */
if (!indirect) clen++;
if ((slen & 0xc0) == 0xc0)
{
if (!indirect)
clen++;
indirect = 1;
/* Follow indirection */
cp = &msg[((slen & 0x3f)<<8) + *cp];
slen = *cp++;
}
if (slen == 0) /* zero length == all done */
break;
len -= slen + 1;
if (len < 0) return -1;
if (!indirect) clen += slen;
while (slen-- != 0) *buf++ = (char)*cp++;
*buf++ = '.';
nseg++;
}
if (nseg == 0)
{
/* Root name; represent as single dot */
*buf++ = '.';
len--;
}
*buf++ = '\0';
len--;
return clen; /* Length of compressed message */
}
/*
* PARSE QUESTION SECTION
*
* Description : This function parses the question record of the reply message.
* Arguments : msg - is a pointer to the reply message
* cp - is a pointer to the question record.
* Returns : a pointer the to next record.
*/
uint8_t * dns_question(uint8_t * msg, uint8_t * cp)
{
int len;
char name[MAXCNAME];
len = parse_name(msg, cp, name, MAXCNAME);
if (len == -1) return 0;
cp += len;
cp += 2; /* type */
cp += 2; /* class */
return cp;
}
/*
* PARSE ANSER SECTION
*
* Description : This function parses the answer record of the reply message.
* Arguments : msg - is a pointer to the reply message
* cp - is a pointer to the answer record.
* Returns : a pointer the to next record.
*/
uint8_t * dns_answer(uint8_t * msg, uint8_t * cp, uint8_t * ip_from_dns)
{
int len, type;
char name[MAXCNAME];
len = parse_name(msg, cp, name, MAXCNAME);
if (len == -1) return 0;
cp += len;
type = get16(cp);
cp += 2; /* type */
cp += 2; /* class */
cp += 4; /* ttl */
cp += 2; /* len */
switch (type)
{
case TYPE_A:
/* Just read the address directly into the structure */
ip_from_dns[0] = *cp++;
ip_from_dns[1] = *cp++;
ip_from_dns[2] = *cp++;
ip_from_dns[3] = *cp++;
break;
case TYPE_CNAME:
case TYPE_MB:
case TYPE_MG:
case TYPE_MR:
case TYPE_NS:
case TYPE_PTR:
/* These types all consist of a single domain name */
/* convert it to ASCII format */
len = parse_name(msg, cp, name, MAXCNAME);
if (len == -1) return 0;
cp += len;
break;
case TYPE_HINFO:
len = *cp++;
cp += len;
len = *cp++;
cp += len;
break;
case TYPE_MX:
cp += 2;
/* Get domain name of exchanger */
len = parse_name(msg, cp, name, MAXCNAME);
if (len == -1) return 0;
cp += len;
break;
case TYPE_SOA:
/* Get domain name of name server */
len = parse_name(msg, cp, name, MAXCNAME);
if (len == -1) return 0;
cp += len;
/* Get domain name of responsible person */
len = parse_name(msg, cp, name, MAXCNAME);
if (len == -1) return 0;
cp += len;
cp += 4;
cp += 4;
cp += 4;
cp += 4;
cp += 4;
break;
case TYPE_TXT:
/* Just stash */
break;
default:
/* Ignore */
break;
}
return cp;
}
/*
* PARSE THE DNS REPLY
*
* Description : This function parses the reply message from DNS server.
* Arguments : dhdr - is a pointer to the header for DNS message
* buf - is a pointer to the reply message.
* len - is the size of reply message.
* Returns : -1 - Domain name length is too big
* 0 - Fail (Timeout or parse error)
* 1 - Success,
*/
int8_t parseDNSMSG(struct dhdr * pdhdr, uint8_t * pbuf, uint8_t * ip_from_dns)
{
uint16_t tmp;
uint16_t i;
uint8_t * msg;
uint8_t * cp;
msg = pbuf;
memset(pdhdr, 0, sizeof(*pdhdr));
pdhdr->id = get16(&msg[0]);
tmp = get16(&msg[2]);
if (tmp & 0x8000) pdhdr->qr = 1;
pdhdr->opcode = (tmp >> 11) & 0xf;
if (tmp & 0x0400) pdhdr->aa = 1;
if (tmp & 0x0200) pdhdr->tc = 1;
if (tmp & 0x0100) pdhdr->rd = 1;
if (tmp & 0x0080) pdhdr->ra = 1;
pdhdr->rcode = tmp & 0xf;
pdhdr->qdcount = get16(&msg[4]);
pdhdr->ancount = get16(&msg[6]);
pdhdr->nscount = get16(&msg[8]);
pdhdr->arcount = get16(&msg[10]);
/* Now parse the variable length sections */
cp = &msg[12];
/* Question section */
for (i = 0; i < pdhdr->qdcount; i++)
{
cp = dns_question(msg, cp);
if(!cp)
{
#ifdef _DNS_DEBUG_
printf("MAX_DOMAIN_NAME is too small, it should be redefined in dns.h\r\n");
#endif
return -1;
}
}
/* Answer section */
for (i = 0; i < pdhdr->ancount; i++)
{
cp = dns_answer(msg, cp, ip_from_dns);
if(!cp)
{
#ifdef _DNS_DEBUG_
printf("MAX_DOMAIN_NAME is too small, it should be redefined in dns.h\r\n");
#endif
return -1;
}
}
/* Name server (authority) section */
for (i = 0; i < pdhdr->nscount; i++)
{
;
}
/* Additional section */
for (i = 0; i < pdhdr->arcount; i++)
{
;
}
if(pdhdr->rcode == 0) return 1; // No error
else return 0;
}
/*
* MAKE DNS QUERY MESSAGE
*
* Description : This function makes DNS query message.
* Arguments : op - Recursion desired
* name - is a pointer to the domain name.
* buf - is a pointer to the buffer for DNS message.
* len - is the MAX. size of buffer.
* Returns : the pointer to the DNS message.
*/
int16_t dns_makequery(uint16_t op, char * name, uint8_t * buf, uint16_t len)
{
uint8_t *cp;
char *cp1;
char sname[MAXCNAME];
char *dname;
uint16_t p;
uint16_t dlen;
cp = buf;
DNS_MSGID++;
cp = put16(cp, DNS_MSGID);
p = (op << 11) | 0x0100; /* Recursion desired */
cp = put16(cp, p);
cp = put16(cp, 1);
cp = put16(cp, 0);
cp = put16(cp, 0);
cp = put16(cp, 0);
strcpy(sname, name);
dname = sname;
dlen = strlen(dname);
for (;;)
{
/* Look for next dot */
cp1 = strchr(dname, '.');
if (cp1 != NULL) len = cp1 - dname; /* More to come */
else len = dlen; /* Last component */
*cp++ = len; /* Write length of component */
if (len == 0) break;
/* Copy component up to (but not including) dot */
memcpy(cp, dname, len);
cp += len;
if (cp1 == NULL)
{
*cp++ = 0; /* Last one; write null and finish */
break;
}
dname += len+1;
dlen -= len+1;
}
cp = put16(cp, 0x0001); /* type */
cp = put16(cp, 0x0001); /* class */
return ((int16_t)((uint32_t)(cp) - (uint32_t)(buf)));
}
/*
* CHECK DNS TIMEOUT
*
* Description : This function check the DNS timeout
* Arguments : None.
* Returns : -1 - timeout occurred, 0 - timer over, but no timeout, 1 - no timer over, no timeout occur
* Note : timeout : retry count and timer both over.
*/
int8_t check_DNS_timeout(void)
{
static uint8_t retry_count;
uint32_t tick = HAL_GetTick();
if(tick - hal_sys_tick >= DNS_WAIT_TIME * 1000)
{
hal_sys_tick = tick;
if(retry_count >= MAX_DNS_RETRY) {
retry_count = 0;
return -1; // timeout occurred
}
retry_count++;
return 0; // timer over, but no timeout
}
return 1; // no timer over, no timeout occur
}
/* DNS CLIENT INIT */
void DNS_init(uint8_t s, uint8_t * buf)
{
DNS_SOCKET = s; // SOCK_DNS
pDNSMSG = buf; // User's shared buffer
DNS_MSGID = DNS_MSG_ID;
}
/* DNS CLIENT RUN */
int8_t DNS_run(uint8_t * dns_ip, uint8_t * name, uint8_t * ip_from_dns)
{
int8_t ret;
struct dhdr dhp;
uint8_t ip[4];
uint16_t len, port;
int8_t ret_check_timeout;
hal_sys_tick = HAL_GetTick();
// Socket open
WIZCHIP_EXPORT(socket)(DNS_SOCKET, Sn_MR_UDP, 0, 0);
#ifdef _DNS_DEBUG_
printf("> DNS Query to DNS Server : %d.%d.%d.%d\r\n", dns_ip[0], dns_ip[1], dns_ip[2], dns_ip[3]);
#endif
len = dns_makequery(0, (char *)name, pDNSMSG, MAX_DNS_BUF_SIZE);
WIZCHIP_EXPORT(sendto)(DNS_SOCKET, pDNSMSG, len, dns_ip, IPPORT_DOMAIN);
while (1)
{
if ((len = getSn_RX_RSR(DNS_SOCKET)) > 0)
{
if (len > MAX_DNS_BUF_SIZE) len = MAX_DNS_BUF_SIZE;
len = WIZCHIP_EXPORT(recvfrom)(DNS_SOCKET, pDNSMSG, len, ip, &port);
#ifdef _DNS_DEBUG_
printf("> Receive DNS message from %d.%d.%d.%d(%d). len = %d\r\n", ip[0], ip[1], ip[2], ip[3],port,len);
#endif
ret = parseDNSMSG(&dhp, pDNSMSG, ip_from_dns);
break;
}
// Check Timeout
ret_check_timeout = check_DNS_timeout();
if (ret_check_timeout < 0) {
#ifdef _DNS_DEBUG_
printf("> DNS Server is not responding : %d.%d.%d.%d\r\n", dns_ip[0], dns_ip[1], dns_ip[2], dns_ip[3]);
#endif
return 0; // timeout occurred
}
else if (ret_check_timeout == 0) {
#ifdef _DNS_DEBUG_
printf("> DNS Timeout\r\n");
#endif
WIZCHIP_EXPORT(sendto)(DNS_SOCKET, pDNSMSG, len, dns_ip, IPPORT_DOMAIN);
}
}
WIZCHIP_EXPORT(close)(DNS_SOCKET);
// Return value
// 0 > : failed / 1 - success
return ret;
}

View file

@ -1,96 +0,0 @@
//*****************************************************************************
//
//! \file dns.h
//! \brief DNS APIs Header file.
//! \details Send DNS query & Receive DNS reponse.
//! \version 1.1.0
//! \date 2013/11/18
//! \par Revision history
//! <2013/10/21> 1st Release
//! <2013/12/20> V1.1.0
//! 1. Remove secondary DNS server in DNS_run
//! If 1st DNS_run failed, call DNS_run with 2nd DNS again
//! 2. DNS_timerHandler -> DNS_time_handler
//! 3. Move the no reference define to dns.c
//! 4. Integrated dns.h dns.c & dns_parse.h dns_parse.c into dns.h & dns.c
//! <2013/12/20> V1.1.0
//!
//! \author Eric Jung & MidnightCow
//! \copyright
//!
//! Copyright (c) 2013, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
#ifndef _DNS_H_
#define _DNS_H_
#include <stdint.h>
/*
* @brief Define it for Debug & Monitor DNS processing.
* @note If defined, it depends on <stdio.h>
*/
//#define _DNS_DEBUG_
#define MAX_DNS_BUF_SIZE 256 ///< maximum size of DNS buffer. */
/*
* @brief Maximum length of your queried Domain name
* @todo SHOULD BE defined it equal as or greater than your Domain name length + null character(1)
* @note SHOULD BE careful to stack overflow because it is allocated 1.5 times as MAX_DOMAIN_NAME in stack.
*/
#define MAX_DOMAIN_NAME 32 // for example "www.google.com"
#define MAX_DNS_RETRY 2 ///< Requery Count
#define DNS_WAIT_TIME 4 ///< Wait response time. unit 1s.
#define IPPORT_DOMAIN 53 ///< DNS server port number
#define DNS_MSG_ID 0x1122 ///< ID for DNS message. You can be modified it any number
/*
* @brief DNS process initialize
* @param s : Socket number for DNS
* @param buf : Buffer for DNS message
*/
void DNS_init(uint8_t s, uint8_t * buf);
/*
* @brief DNS process
* @details Send DNS query and receive DNS response
* @param dns_ip : DNS server ip address
* @param name : Domain name to be queried
* @param ip_from_dns : IP address from DNS server
* @return -1 : failed. @ref MAX_DOMIN_NAME is too small \n
* 0 : failed (Timeout or Parse error)\n
* 1 : success
* @note This function blocks until success or fail. max time = @ref MAX_DNS_RETRY * @ref DNS_WAIT_TIME
*/
int8_t DNS_run(uint8_t * dns_ip, uint8_t * name, uint8_t * ip_from_dns);
#endif /* _DNS_H_ */

View file

@ -0,0 +1,117 @@
/*
* Automatically generated header file: don't edit
*/
#define HAVE_DOT_CONFIG 1
#define CONFIG_PLATFORM_LINUX 1
#undef CONFIG_PLATFORM_CYGWIN
#undef CONFIG_PLATFORM_WIN32
/*
* General Configuration
*/
#define PREFIX "/usr/local"
#undef CONFIG_DEBUG
#undef CONFIG_STRIP_UNWANTED_SECTIONS
#undef CONFIG_VISUAL_STUDIO_7_0
#undef CONFIG_VISUAL_STUDIO_8_0
#undef CONFIG_VISUAL_STUDIO_10_0
#define CONFIG_VISUAL_STUDIO_7_0_BASE ""
#define CONFIG_VISUAL_STUDIO_8_0_BASE ""
#define CONFIG_VISUAL_STUDIO_10_0_BASE ""
#define CONFIG_EXTRA_CFLAGS_OPTIONS ""
#define CONFIG_EXTRA_LDFLAGS_OPTIONS ""
/*
* SSL Library
*/
#undef CONFIG_SSL_SERVER_ONLY
#undef CONFIG_SSL_CERT_VERIFICATION
#undef CONFIG_SSL_FULL_MODE
#define CONFIG_SSL_SKELETON_MODE 1
#define CONFIG_SSL_ENABLE_SERVER 1
#define CONFIG_SSL_ENABLE_CLIENT 1
#undef CONFIG_SSL_DIAGNOSTICS
#define CONFIG_SSL_PROT_LOW 1
#undef CONFIG_SSL_PROT_MEDIUM
#undef CONFIG_SSL_PROT_HIGH
#define CONFIG_SSL_AES 1
#define CONFIG_SSL_USE_DEFAULT_KEY 1
#define CONFIG_SSL_PRIVATE_KEY_LOCATION ""
#define CONFIG_SSL_PRIVATE_KEY_PASSWORD ""
#define CONFIG_SSL_X509_CERT_LOCATION ""
#undef CONFIG_SSL_GENERATE_X509_CERT
#define CONFIG_SSL_X509_COMMON_NAME ""
#define CONFIG_SSL_X509_ORGANIZATION_NAME ""
#define CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME ""
#undef CONFIG_SSL_HAS_PEM
#undef CONFIG_SSL_USE_PKCS12
#define CONFIG_SSL_EXPIRY_TIME
#define CONFIG_X509_MAX_CA_CERTS 0
#define CONFIG_SSL_MAX_CERTS 3
#undef CONFIG_SSL_CTX_MUTEXING
#undef CONFIG_USE_DEV_URANDOM
#undef CONFIG_WIN32_USE_CRYPTO_LIB
#undef CONFIG_OPENSSL_COMPATIBLE
#undef CONFIG_PERFORMANCE_TESTING
#undef CONFIG_SSL_TEST
#undef CONFIG_AXTLSWRAP
#undef CONFIG_AXHTTPD
#undef CONFIG_HTTP_STATIC_BUILD
#define CONFIG_HTTP_PORT
#define CONFIG_HTTP_HTTPS_PORT
#define CONFIG_HTTP_SESSION_CACHE_SIZE
#define CONFIG_HTTP_WEBROOT ""
#define CONFIG_HTTP_TIMEOUT
#undef CONFIG_HTTP_HAS_CGI
#define CONFIG_HTTP_CGI_EXTENSIONS ""
#undef CONFIG_HTTP_ENABLE_LUA
#define CONFIG_HTTP_LUA_PREFIX ""
#undef CONFIG_HTTP_BUILD_LUA
#define CONFIG_HTTP_CGI_LAUNCHER ""
#undef CONFIG_HTTP_DIRECTORIES
#undef CONFIG_HTTP_HAS_AUTHORIZATION
#undef CONFIG_HTTP_HAS_IPV6
#undef CONFIG_HTTP_ENABLE_DIFFERENT_USER
#define CONFIG_HTTP_USER ""
#undef CONFIG_HTTP_VERBOSE
#undef CONFIG_HTTP_IS_DAEMON
/*
* Language Bindings
*/
#undef CONFIG_BINDINGS
#undef CONFIG_CSHARP_BINDINGS
#undef CONFIG_VBNET_BINDINGS
#define CONFIG_DOT_NET_FRAMEWORK_BASE ""
#undef CONFIG_JAVA_BINDINGS
#define CONFIG_JAVA_HOME ""
#undef CONFIG_PERL_BINDINGS
#define CONFIG_PERL_CORE ""
#define CONFIG_PERL_LIB ""
#undef CONFIG_LUA_BINDINGS
#define CONFIG_LUA_CORE ""
/*
* Samples
*/
#undef CONFIG_SAMPLES
#undef CONFIG_C_SAMPLES
#undef CONFIG_CSHARP_SAMPLES
#undef CONFIG_VBNET_SAMPLES
#undef CONFIG_JAVA_SAMPLES
#undef CONFIG_PERL_SAMPLES
#undef CONFIG_LUA_SAMPLES
#undef CONFIG_BIGINT_CLASSICAL
#undef CONFIG_BIGINT_MONTGOMERY
#undef CONFIG_BIGINT_BARRETT
#undef CONFIG_BIGINT_CRT
#undef CONFIG_BIGINT_KARATSUBA
#define MUL_KARATSUBA_THRESH
#define SQU_KARATSUBA_THRESH
#undef CONFIG_BIGINT_SLIDING_WINDOW
#undef CONFIG_BIGINT_SQUARE
#undef CONFIG_BIGINT_CHECK_ON
#undef CONFIG_INTEGER_32BIT
#undef CONFIG_INTEGER_16BIT
#undef CONFIG_INTEGER_8BIT

View file

@ -0,0 +1 @@
#define AXTLS_VERSION "(no version)"

View file

@ -14,6 +14,7 @@
/*************************** HEADER FILES ***************************/ /*************************** HEADER FILES ***************************/
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include "sha256.h" #include "sha256.h"
/****************************** MACROS ******************************/ /****************************** MACROS ******************************/

View file

@ -1,82 +0,0 @@
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
// SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George
//
// SPDX-License-Identifier: MIT
#include "py/runtime.h"
#include "extmod/machine_mem.h"
#if MICROPY_PY_MACHINE
// If you wish to override the functions for mapping the machine_mem read/write
// address, then add a #define for MICROPY_MACHINE_MEM_GET_READ_ADDR and/or
// MICROPY_MACHINE_MEM_GET_WRITE_ADDR in your mpconfigport.h. Since the
// prototypes are identical, it is allowable for both of the macros to evaluate
// the to same function.
//
// It is expected that the modmachine.c file for a given port will provide the
// implementations, if the default implementation isn't used.
#if !defined(MICROPY_MACHINE_MEM_GET_READ_ADDR) || !defined(MICROPY_MACHINE_MEM_GET_WRITE_ADDR)
STATIC uintptr_t machine_mem_get_addr(mp_obj_t addr_o, uint align) {
uintptr_t addr = mp_obj_int_get_truncated(addr_o);
if ((addr & (align - 1)) != 0) {
mp_raise_ValueError_varg(translate("address %08x is not aligned to %d bytes"), addr, align);
}
return addr;
}
#if !defined(MICROPY_MACHINE_MEM_GET_READ_ADDR)
#define MICROPY_MACHINE_MEM_GET_READ_ADDR machine_mem_get_addr
#endif
#if !defined(MICROPY_MACHINE_MEM_GET_WRITE_ADDR)
#define MICROPY_MACHINE_MEM_GET_WRITE_ADDR machine_mem_get_addr
#endif
#endif
STATIC void machine_mem_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
(void)kind;
machine_mem_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_printf(print, "<%u-bit memory>", 8 * self->elem_size);
}
STATIC mp_obj_t machine_mem_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
// TODO support slice index to read/write multiple values at once
machine_mem_obj_t *self = MP_OBJ_TO_PTR(self_in);
if (value == MP_OBJ_NULL) {
// delete
return MP_OBJ_NULL; // op not supported
} else if (value == MP_OBJ_SENTINEL) {
// load
uintptr_t addr = MICROPY_MACHINE_MEM_GET_READ_ADDR(index, self->elem_size);
uint32_t val;
switch (self->elem_size) {
case 1: val = (*(uint8_t*)addr); break;
case 2: val = (*(uint16_t*)addr); break;
default: val = (*(uint32_t*)addr); break;
}
return mp_obj_new_int(val);
} else {
// store
uintptr_t addr = MICROPY_MACHINE_MEM_GET_WRITE_ADDR(index, self->elem_size);
uint32_t val = mp_obj_get_int_truncated(value);
switch (self->elem_size) {
case 1: (*(uint8_t*)addr) = val; break;
case 2: (*(uint16_t*)addr) = val; break;
default: (*(uint32_t*)addr) = val; break;
}
return mp_const_none;
}
}
const mp_obj_type_t machine_mem_type = {
{ &mp_type_type },
.name = MP_QSTR_mem,
.print = machine_mem_print,
.subscr = machine_mem_subscr,
};
const machine_mem_obj_t machine_mem8_obj = {{&machine_mem_type}, 1};
const machine_mem_obj_t machine_mem16_obj = {{&machine_mem_type}, 2};
const machine_mem_obj_t machine_mem32_obj = {{&machine_mem_type}, 4};
#endif // MICROPY_PY_MACHINE

View file

@ -1,29 +0,0 @@
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
// SPDX-FileCopyrightText: Copyright (c) 2015 Damien P. George
//
// SPDX-License-Identifier: MIT
#ifndef MICROPY_INCLUDED_EXTMOD_MACHINE_MEM_H
#define MICROPY_INCLUDED_EXTMOD_MACHINE_MEM_H
#include "py/obj.h"
typedef struct _machine_mem_obj_t {
mp_obj_base_t base;
unsigned elem_size; // in bytes
} machine_mem_obj_t;
extern const mp_obj_type_t machine_mem_type;
extern const machine_mem_obj_t machine_mem8_obj;
extern const machine_mem_obj_t machine_mem16_obj;
extern const machine_mem_obj_t machine_mem32_obj;
#if defined(MICROPY_MACHINE_MEM_GET_READ_ADDR)
uintptr_t MICROPY_MACHINE_MEM_GET_READ_ADDR(mp_obj_t addr_o, uint align);
#endif
#if defined(MICROPY_MACHINE_MEM_GET_WRITE_ADDR)
uintptr_t MICROPY_MACHINE_MEM_GET_WRITE_ADDR(mp_obj_t addr_o, uint align);
#endif
#endif // MICROPY_INCLUDED_EXTMOD_MACHINE_MEM_H

View file

@ -1,67 +0,0 @@
// Copyright (c) 2016 Paul Sokolovsky
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
//
// SPDX-License-Identifier: MIT
#include "py/mpconfig.h"
#if MICROPY_PY_MACHINE
#include "py/obj.h"
#include "py/runtime.h"
#include "extmod/virtpin.h"
#include "extmod/machine_pinbase.h"
// PinBase class
// As this is abstract class, its instance is null.
// But there should be an instance, as the rest of instance code
// expects that there will be concrete object for inheritance.
typedef struct _mp_pinbase_t {
mp_obj_base_t base;
} mp_pinbase_t;
STATIC const mp_pinbase_t pinbase_singleton = {
.base = { &machine_pinbase_type },
};
STATIC mp_obj_t pinbase_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
(void)type;
(void)n_args;
(void)args;
(void)kw_args;
return MP_OBJ_FROM_PTR(&pinbase_singleton);
}
mp_uint_t pinbase_ioctl(mp_obj_t obj, mp_uint_t request, uintptr_t arg, int *errcode);
mp_uint_t pinbase_ioctl(mp_obj_t obj, mp_uint_t request, uintptr_t arg, int *errcode) {
(void)errcode;
switch (request) {
case MP_PIN_READ: {
mp_obj_t dest[2];
mp_load_method(obj, MP_QSTR_value, dest);
return mp_obj_get_int(mp_call_method_n_kw(0, 0, dest));
}
case MP_PIN_WRITE: {
mp_obj_t dest[3];
mp_load_method(obj, MP_QSTR_value, dest);
dest[2] = (arg == 0 ? mp_const_false : mp_const_true);
mp_call_method_n_kw(1, 0, dest);
return 0;
}
}
return -1;
}
STATIC const mp_pin_p_t pinbase_pin_p = {
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_pin)
.ioctl = pinbase_ioctl,
};
const mp_obj_type_t machine_pinbase_type = {
{ &mp_type_type },
.name = MP_QSTR_PinBase,
.make_new = pinbase_make_new,
.protocol = &pinbase_pin_p,
};
#endif // MICROPY_PY_MACHINE

View file

@ -1,13 +0,0 @@
// Copyright (c) 2016 Paul Sokolovsky
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
//
// SPDX-License-Identifier: MIT
#ifndef MICROPY_INCLUDED_EXTMOD_MACHINE_PINBASE_H
#define MICROPY_INCLUDED_EXTMOD_MACHINE_PINBASE_H
#include "py/obj.h"
extern const mp_obj_type_t machine_pinbase_type;
#endif // MICROPY_INCLUDED_EXTMOD_MACHINE_PINBASE_H

View file

@ -1,44 +0,0 @@
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
// SPDX-FileCopyrightText: Copyright (c) 2016 Damien P. George
//
// SPDX-License-Identifier: MIT
#include "py/runtime.h"
#include "py/mperrno.h"
#include "extmod/machine_pulse.h"
#if MICROPY_PY_MACHINE_PULSE
mp_uint_t machine_time_pulse_us(mp_hal_pin_obj_t pin, int pulse_level, mp_uint_t timeout_us) {
mp_uint_t start = mp_hal_ticks_us();
while (mp_hal_pin_read(pin) != pulse_level) {
if ((mp_uint_t)(mp_hal_ticks_us() - start) >= timeout_us) {
return (mp_uint_t)-2;
}
}
start = mp_hal_ticks_us();
while (mp_hal_pin_read(pin) == pulse_level) {
if ((mp_uint_t)(mp_hal_ticks_us() - start) >= timeout_us) {
return (mp_uint_t)-1;
}
}
return mp_hal_ticks_us() - start;
}
STATIC mp_obj_t machine_time_pulse_us_(size_t n_args, const mp_obj_t *args) {
mp_hal_pin_obj_t pin = mp_hal_get_pin_obj(args[0]);
int level = 0;
if (mp_obj_is_true(args[1])) {
level = 1;
}
mp_uint_t timeout_us = 1000000;
if (n_args > 2) {
timeout_us = mp_obj_get_int(args[2]);
}
mp_uint_t us = machine_time_pulse_us(pin, level, timeout_us);
// May return -1 or -2 in case of timeout
return mp_obj_new_int(us);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_time_pulse_us_obj, 2, 3, machine_time_pulse_us_);
#endif

View file

@ -1,16 +0,0 @@
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
// SPDX-FileCopyrightText: Copyright (c) 2016 Damien P. George
//
// SPDX-License-Identifier: MIT
#ifndef MICROPY_INCLUDED_EXTMOD_MACHINE_PULSE_H
#define MICROPY_INCLUDED_EXTMOD_MACHINE_PULSE_H
#include "py/obj.h"
#include "py/mphal.h"
mp_uint_t machine_time_pulse_us(mp_hal_pin_obj_t pin, int pulse_level, mp_uint_t timeout_us);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(machine_time_pulse_us_obj);
#endif // MICROPY_INCLUDED_EXTMOD_MACHINE_PULSE_H

View file

@ -1,160 +0,0 @@
// Copyright (c) 2017 Paul Sokolovsky
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
//
// SPDX-License-Identifier: MIT
#include "py/mpconfig.h"
#if MICROPY_PY_MACHINE
#include <string.h>
#include "py/obj.h"
#include "py/runtime.h"
#include "extmod/virtpin.h"
#include "extmod/machine_signal.h"
// Signal class
typedef struct _machine_signal_t {
mp_obj_base_t base;
mp_obj_t pin;
bool invert;
} machine_signal_t;
STATIC mp_obj_t signal_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
mp_obj_t pin = args[0];
bool invert = false;
#if defined(MICROPY_PY_MACHINE_PIN_MAKE_NEW)
mp_pin_p_t *pin_p = (mp_pin_t*)mp_proto_get(QSTR_pin_protocol, pin);
if (pin_p == NULL) {
// If first argument isn't a Pin-like object, we filter out "invert"
// from keyword arguments and pass them all to the exported Pin
// constructor to create one.
mp_obj_t *pin_args = mp_local_alloc((n_args + n_kw * 2) * sizeof(mp_obj_t));
memcpy(pin_args, args, n_args * sizeof(mp_obj_t));
const mp_obj_t *src = args + n_args;
mp_obj_t *dst = pin_args + n_args;
mp_obj_t *sig_value = NULL;
for (size_t cnt = n_kw; cnt; cnt--) {
if (*src == MP_OBJ_NEW_QSTR(MP_QSTR_invert)) {
invert = mp_obj_is_true(src[1]);
n_kw--;
} else {
*dst++ = *src;
*dst++ = src[1];
}
if (*src == MP_OBJ_NEW_QSTR(MP_QSTR_value)) {
// Value is pertained to Signal, so we should invert
// it for Pin if needed, and we should do it only when
// inversion status is guaranteedly known.
sig_value = dst - 1;
}
src += 2;
}
if (invert && sig_value != NULL) {
*sig_value = mp_obj_is_true(*sig_value) ? MP_OBJ_NEW_SMALL_INT(0) : MP_OBJ_NEW_SMALL_INT(1);
}
// Here we pass NULL as a type, hoping that mp_pin_make_new()
// will just ignore it as set a concrete type. If not, we'd need
// to expose port's "default" pin type too.
pin = MICROPY_PY_MACHINE_PIN_MAKE_NEW(NULL, n_args, n_kw, pin_args);
mp_local_free(pin_args);
}
else
#endif
// Otherwise there should be 1 or 2 args
{
if (n_args == 1) {
if (kw_args == NULL || kw_args->used == 0) {
} else if (kw_args->used == 1 && kw_args->table[0].key == MP_OBJ_NEW_QSTR(MP_QSTR_invert)) {
invert = mp_obj_is_true(kw_args->table[0].value);
} else {
goto error;
}
} else {
error:
mp_raise_TypeError(NULL);
}
}
machine_signal_t *o = m_new_obj(machine_signal_t);
o->base.type = type;
o->pin = pin;
o->invert = invert;
return MP_OBJ_FROM_PTR(o);
}
STATIC mp_uint_t signal_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
(void)errcode;
machine_signal_t *self = MP_OBJ_TO_PTR(self_in);
switch (request) {
case MP_PIN_READ: {
return mp_virtual_pin_read(self->pin) ^ self->invert;
}
case MP_PIN_WRITE: {
mp_virtual_pin_write(self->pin, arg ^ self->invert);
return 0;
}
}
return -1;
}
// fast method for getting/setting signal value
STATIC mp_obj_t signal_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num_kw_array(n_args, n_kw, 0, 1, false);
if (n_args == 0) {
// get pin
return MP_OBJ_NEW_SMALL_INT(mp_virtual_pin_read(self_in));
} else {
// set pin
mp_virtual_pin_write(self_in, mp_obj_is_true(args[0]));
return mp_const_none;
}
}
STATIC mp_obj_t signal_value(size_t n_args, const mp_obj_t *args) {
return signal_call(args[0], n_args - 1, 0, args + 1);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(signal_value_obj, 1, 2, signal_value);
STATIC mp_obj_t signal_on(mp_obj_t self_in) {
mp_virtual_pin_write(self_in, 1);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(signal_on_obj, signal_on);
STATIC mp_obj_t signal_off(mp_obj_t self_in) {
mp_virtual_pin_write(self_in, 0);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(signal_off_obj, signal_off);
STATIC const mp_rom_map_elem_t signal_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&signal_value_obj) },
{ MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&signal_on_obj) },
{ MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&signal_off_obj) },
};
STATIC MP_DEFINE_CONST_DICT(signal_locals_dict, signal_locals_dict_table);
STATIC const mp_pin_p_t signal_pin_p = {
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_pin)
.ioctl = signal_ioctl,
};
const mp_obj_type_t machine_signal_type = {
{ &mp_type_type },
.name = MP_QSTR_Signal,
.make_new = signal_make_new,
.call = signal_call,
.protocol = &signal_pin_p,
.locals_dict = (void*)&signal_locals_dict,
};
#endif // MICROPY_PY_MACHINE

View file

@ -1,13 +0,0 @@
// Copyright (c) 2017 Paul Sokolovsky
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
//
// SPDX-License-Identifier: MIT
#ifndef MICROPY_INCLUDED_EXTMOD_MACHINE_SIGNAL_H
#define MICROPY_INCLUDED_EXTMOD_MACHINE_SIGNAL_H
#include "py/obj.h"
extern const mp_obj_type_t machine_signal_type;
#endif // MICROPY_INCLUDED_EXTMOD_MACHINE_SIGNAL_H

View file

@ -34,9 +34,9 @@ typedef struct _mp_obj_btree_t {
STATIC const mp_obj_type_t btree_type; STATIC const mp_obj_type_t btree_type;
#define CHECK_ERROR(res) \ #define CHECK_ERROR(res) \
if (res == RET_ERROR) { \ if (res == RET_ERROR) { \
mp_raise_OSError(errno); \ mp_raise_OSError(errno); \
} }
void __dbpanic(DB *db) { void __dbpanic(DB *db) {
printf("__dbpanic(%p)\n", db); printf("__dbpanic(%p)\n", db);
@ -74,8 +74,8 @@ STATIC mp_obj_t btree_put(size_t n_args, const mp_obj_t *args) {
(void)n_args; (void)n_args;
mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]); mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]);
DBT key, val; DBT key, val;
key.data = (void*)mp_obj_str_get_data(args[1], &key.size); key.data = (void *)mp_obj_str_get_data(args[1], &key.size);
val.data = (void*)mp_obj_str_get_data(args[2], &val.size); val.data = (void *)mp_obj_str_get_data(args[2], &val.size);
return MP_OBJ_NEW_SMALL_INT(__bt_put(self->db, &key, &val, 0)); return MP_OBJ_NEW_SMALL_INT(__bt_put(self->db, &key, &val, 0));
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_put_obj, 3, 4, btree_put); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_put_obj, 3, 4, btree_put);
@ -83,7 +83,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_put_obj, 3, 4, btree_put);
STATIC mp_obj_t btree_get(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t btree_get(size_t n_args, const mp_obj_t *args) {
mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]); mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]);
DBT key, val; DBT key, val;
key.data = (void*)mp_obj_str_get_data(args[1], &key.size); key.data = (void *)mp_obj_str_get_data(args[1], &key.size);
int res = __bt_get(self->db, &key, &val, 0); int res = __bt_get(self->db, &key, &val, 0);
if (res == RET_SPECIAL) { if (res == RET_SPECIAL) {
if (n_args > 2) { if (n_args > 2) {
@ -102,7 +102,7 @@ STATIC mp_obj_t btree_seq(size_t n_args, const mp_obj_t *args) {
int flags = MP_OBJ_SMALL_INT_VALUE(args[1]); int flags = MP_OBJ_SMALL_INT_VALUE(args[1]);
DBT key, val; DBT key, val;
if (n_args > 2) { if (n_args > 2) {
key.data = (void*)mp_obj_str_get_data(args[2], &key.size); key.data = (void *)mp_obj_str_get_data(args[2], &key.size);
} }
int res = __bt_seq(self->db, &key, &val, flags); int res = __bt_seq(self->db, &key, &val, flags);
@ -177,7 +177,7 @@ STATIC mp_obj_t btree_iternext(mp_obj_t self_in) {
if (self->start_key != MP_OBJ_NULL) { if (self->start_key != MP_OBJ_NULL) {
int flags = R_FIRST; int flags = R_FIRST;
if (self->start_key != mp_const_none) { if (self->start_key != mp_const_none) {
key.data = (void*)mp_obj_str_get_data(self->start_key, &key.size); key.data = (void *)mp_obj_str_get_data(self->start_key, &key.size);
flags = R_CURSOR; flags = R_CURSOR;
} else if (desc) { } else if (desc) {
flags = R_LAST; flags = R_LAST;
@ -195,7 +195,7 @@ STATIC mp_obj_t btree_iternext(mp_obj_t self_in) {
if (self->end_key != mp_const_none) { if (self->end_key != mp_const_none) {
DBT end_key; DBT end_key;
end_key.data = (void*)mp_obj_str_get_data(self->end_key, &end_key.size); end_key.data = (void *)mp_obj_str_get_data(self->end_key, &end_key.size);
BTREE *t = self->db->internal; BTREE *t = self->db->internal;
int cmp = t->bt_cmp(&key, &end_key); int cmp = t->bt_cmp(&key, &end_key);
if (desc) { if (desc) {
@ -230,7 +230,7 @@ STATIC mp_obj_t btree_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
if (value == MP_OBJ_NULL) { if (value == MP_OBJ_NULL) {
// delete // delete
DBT key; DBT key;
key.data = (void*)mp_obj_str_get_data(index, &key.size); key.data = (void *)mp_obj_str_get_data(index, &key.size);
int res = __bt_delete(self->db, &key, 0); int res = __bt_delete(self->db, &key, 0);
if (res == RET_SPECIAL) { if (res == RET_SPECIAL) {
nlr_raise(mp_obj_new_exception(&mp_type_KeyError)); nlr_raise(mp_obj_new_exception(&mp_type_KeyError));
@ -240,7 +240,7 @@ STATIC mp_obj_t btree_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
} else if (value == MP_OBJ_SENTINEL) { } else if (value == MP_OBJ_SENTINEL) {
// load // load
DBT key, val; DBT key, val;
key.data = (void*)mp_obj_str_get_data(index, &key.size); key.data = (void *)mp_obj_str_get_data(index, &key.size);
int res = __bt_get(self->db, &key, &val, 0); int res = __bt_get(self->db, &key, &val, 0);
if (res == RET_SPECIAL) { if (res == RET_SPECIAL) {
nlr_raise(mp_obj_new_exception(&mp_type_KeyError)); nlr_raise(mp_obj_new_exception(&mp_type_KeyError));
@ -250,8 +250,8 @@ STATIC mp_obj_t btree_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
} else { } else {
// store // store
DBT key, val; DBT key, val;
key.data = (void*)mp_obj_str_get_data(index, &key.size); key.data = (void *)mp_obj_str_get_data(index, &key.size);
val.data = (void*)mp_obj_str_get_data(value, &val.size); val.data = (void *)mp_obj_str_get_data(value, &val.size);
int res = __bt_put(self->db, &key, &val, 0); int res = __bt_put(self->db, &key, &val, 0);
CHECK_ERROR(res); CHECK_ERROR(res);
return mp_const_none; return mp_const_none;
@ -263,7 +263,7 @@ STATIC mp_obj_t btree_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs
switch (op) { switch (op) {
case MP_BINARY_OP_CONTAINS: { case MP_BINARY_OP_CONTAINS: {
DBT key, val; DBT key, val;
key.data = (void*)mp_obj_str_get_data(rhs_in, &key.size); key.data = (void *)mp_obj_str_get_data(rhs_in, &key.size);
int res = __bt_get(self->db, &key, &val, 0); int res = __bt_get(self->db, &key, &val, 0);
CHECK_ERROR(res); CHECK_ERROR(res);
return mp_obj_new_bool(res != RET_SPECIAL); return mp_obj_new_bool(res != RET_SPECIAL);
@ -296,7 +296,7 @@ STATIC const mp_obj_type_t btree_type = {
.iternext = btree_iternext, .iternext = btree_iternext,
.binary_op = btree_binary_op, .binary_op = btree_binary_op,
.subscr = btree_subscr, .subscr = btree_subscr,
.locals_dict = (void*)&btree_locals_dict, .locals_dict = (void *)&btree_locals_dict,
}; };
STATIC FILEVTABLE btree_stream_fvtable = { STATIC FILEVTABLE btree_stream_fvtable = {
@ -324,14 +324,14 @@ STATIC mp_obj_t mod_btree_open(size_t n_args, const mp_obj_t *pos_args, mp_map_t
mp_arg_val_t minkeypage; mp_arg_val_t minkeypage;
} args; } args;
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args,
MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t*)&args); MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&args);
BTREEINFO openinfo = {0}; BTREEINFO openinfo = {0};
openinfo.flags = args.flags.u_int; openinfo.flags = args.flags.u_int;
openinfo.cachesize = args.cachesize.u_int; openinfo.cachesize = args.cachesize.u_int;
openinfo.psize = args.pagesize.u_int; openinfo.psize = args.pagesize.u_int;
openinfo.minkeypage = args.minkeypage.u_int; openinfo.minkeypage = args.minkeypage.u_int;
DB *db = __bt_open(pos_args[0], &btree_stream_fvtable, &openinfo, /*dflags*/0); DB *db = __bt_open(MP_OBJ_TO_PTR(pos_args[0]), &btree_stream_fvtable, &openinfo, /*dflags*/ 0);
if (db == NULL) { if (db == NULL) {
mp_raise_OSError(errno); mp_raise_OSError(errno);
} }
@ -350,7 +350,7 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_btree_globals, mp_module_btree_globals_tab
const mp_obj_module_t mp_module_btree = { const mp_obj_module_t mp_module_btree = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_btree_globals, .globals = (mp_obj_dict_t *)&mp_module_btree_globals,
}; };
#endif // MICROPY_PY_BTREE #endif // MICROPY_PY_BTREE

View file

@ -22,8 +22,8 @@ typedef struct _mp_obj_framebuf_t {
uint8_t format; uint8_t format;
} mp_obj_framebuf_t; } mp_obj_framebuf_t;
typedef void (*setpixel_t)(const mp_obj_framebuf_t*, int, int, uint32_t); typedef void (*setpixel_t)(const mp_obj_framebuf_t *, int, int, uint32_t);
typedef uint32_t (*getpixel_t)(const mp_obj_framebuf_t*, int, int); typedef uint32_t (*getpixel_t)(const mp_obj_framebuf_t *, int, int);
typedef void (*fill_rect_t)(const mp_obj_framebuf_t *, int, int, int, int, uint32_t); typedef void (*fill_rect_t)(const mp_obj_framebuf_t *, int, int, int, int, uint32_t);
typedef struct _mp_framebuf_p_t { typedef struct _mp_framebuf_p_t {
@ -47,20 +47,20 @@ typedef struct _mp_framebuf_p_t {
STATIC void mono_horiz_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) { STATIC void mono_horiz_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) {
size_t index = (x + y * fb->stride) >> 3; size_t index = (x + y * fb->stride) >> 3;
int offset = fb->format == FRAMEBUF_MHMSB ? x & 0x07 : 7 - (x & 0x07); int offset = fb->format == FRAMEBUF_MHMSB ? x & 0x07 : 7 - (x & 0x07);
((uint8_t*)fb->buf)[index] = (((uint8_t*)fb->buf)[index] & ~(0x01 << offset)) | ((col != 0) << offset); ((uint8_t *)fb->buf)[index] = (((uint8_t *)fb->buf)[index] & ~(0x01 << offset)) | ((col != 0) << offset);
} }
STATIC uint32_t mono_horiz_getpixel(const mp_obj_framebuf_t *fb, int x, int y) { STATIC uint32_t mono_horiz_getpixel(const mp_obj_framebuf_t *fb, int x, int y) {
size_t index = (x + y * fb->stride) >> 3; size_t index = (x + y * fb->stride) >> 3;
int offset = fb->format == FRAMEBUF_MHMSB ? x & 0x07 : 7 - (x & 0x07); int offset = fb->format == FRAMEBUF_MHMSB ? x & 0x07 : 7 - (x & 0x07);
return (((uint8_t*)fb->buf)[index] >> (offset)) & 0x01; return (((uint8_t *)fb->buf)[index] >> (offset)) & 0x01;
} }
STATIC void mono_horiz_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) { STATIC void mono_horiz_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) {
int reverse = fb->format == FRAMEBUF_MHMSB; int reverse = fb->format == FRAMEBUF_MHMSB;
int advance = fb->stride >> 3; int advance = fb->stride >> 3;
while (w--) { while (w--) {
uint8_t *b = &((uint8_t*)fb->buf)[(x >> 3) + y * advance]; uint8_t *b = &((uint8_t *)fb->buf)[(x >> 3) + y * advance];
int offset = reverse ? x & 7 : 7 - (x & 7); int offset = reverse ? x & 7 : 7 - (x & 7);
for (int hh = h; hh; --hh) { for (int hh = h; hh; --hh) {
*b = (*b & ~(0x01 << offset)) | ((col != 0) << offset); *b = (*b & ~(0x01 << offset)) | ((col != 0) << offset);
@ -75,16 +75,16 @@ STATIC void mono_horiz_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int
STATIC void mvlsb_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) { STATIC void mvlsb_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) {
size_t index = (y >> 3) * fb->stride + x; size_t index = (y >> 3) * fb->stride + x;
uint8_t offset = y & 0x07; uint8_t offset = y & 0x07;
((uint8_t*)fb->buf)[index] = (((uint8_t*)fb->buf)[index] & ~(0x01 << offset)) | ((col != 0) << offset); ((uint8_t *)fb->buf)[index] = (((uint8_t *)fb->buf)[index] & ~(0x01 << offset)) | ((col != 0) << offset);
} }
STATIC uint32_t mvlsb_getpixel(const mp_obj_framebuf_t *fb, int x, int y) { STATIC uint32_t mvlsb_getpixel(const mp_obj_framebuf_t *fb, int x, int y) {
return (((uint8_t*)fb->buf)[(y >> 3) * fb->stride + x] >> (y & 0x07)) & 0x01; return (((uint8_t *)fb->buf)[(y >> 3) * fb->stride + x] >> (y & 0x07)) & 0x01;
} }
STATIC void mvlsb_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) { STATIC void mvlsb_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) {
while (h--) { while (h--) {
uint8_t *b = &((uint8_t*)fb->buf)[(y >> 3) * fb->stride + x]; uint8_t *b = &((uint8_t *)fb->buf)[(y >> 3) * fb->stride + x];
uint8_t offset = y & 0x07; uint8_t offset = y & 0x07;
for (int ww = w; ww; --ww) { for (int ww = w; ww; --ww) {
*b = (*b & ~(0x01 << offset)) | ((col != 0) << offset); *b = (*b & ~(0x01 << offset)) | ((col != 0) << offset);
@ -97,15 +97,15 @@ STATIC void mvlsb_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, in
// Functions for RGB565 format // Functions for RGB565 format
STATIC void rgb565_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) { STATIC void rgb565_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) {
((uint16_t*)fb->buf)[x + y * fb->stride] = col; ((uint16_t *)fb->buf)[x + y * fb->stride] = col;
} }
STATIC uint32_t rgb565_getpixel(const mp_obj_framebuf_t *fb, int x, int y) { STATIC uint32_t rgb565_getpixel(const mp_obj_framebuf_t *fb, int x, int y) {
return ((uint16_t*)fb->buf)[x + y * fb->stride]; return ((uint16_t *)fb->buf)[x + y * fb->stride];
} }
STATIC void rgb565_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) { STATIC void rgb565_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) {
uint16_t *b = &((uint16_t*)fb->buf)[x + y * fb->stride]; uint16_t *b = &((uint16_t *)fb->buf)[x + y * fb->stride];
while (h--) { while (h--) {
for (int ww = w; ww; --ww) { for (int ww = w; ww; --ww) {
*b++ = col; *b++ = col;
@ -117,7 +117,7 @@ STATIC void rgb565_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, i
// Functions for GS2_HMSB format // Functions for GS2_HMSB format
STATIC void gs2_hmsb_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) { STATIC void gs2_hmsb_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) {
uint8_t *pixel = &((uint8_t*)fb->buf)[(x + y * fb->stride) >> 2]; uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride) >> 2];
uint8_t shift = (x & 0x3) << 1; uint8_t shift = (x & 0x3) << 1;
uint8_t mask = 0x3 << shift; uint8_t mask = 0x3 << shift;
uint8_t color = (col & 0x3) << shift; uint8_t color = (col & 0x3) << shift;
@ -125,14 +125,14 @@ STATIC void gs2_hmsb_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_
} }
STATIC uint32_t gs2_hmsb_getpixel(const mp_obj_framebuf_t *fb, int x, int y) { STATIC uint32_t gs2_hmsb_getpixel(const mp_obj_framebuf_t *fb, int x, int y) {
uint8_t pixel = ((uint8_t*)fb->buf)[(x + y * fb->stride) >> 2]; uint8_t pixel = ((uint8_t *)fb->buf)[(x + y * fb->stride) >> 2];
uint8_t shift = (x & 0x3) << 1; uint8_t shift = (x & 0x3) << 1;
return (pixel >> shift) & 0x3; return (pixel >> shift) & 0x3;
} }
STATIC void gs2_hmsb_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) { STATIC void gs2_hmsb_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) {
for (int xx=x; xx < x+w; xx++) { for (int xx = x; xx < x + w; xx++) {
for (int yy=y; yy < y+h; yy++) { for (int yy = y; yy < y + h; yy++) {
gs2_hmsb_setpixel(fb, xx, yy, col); gs2_hmsb_setpixel(fb, xx, yy, col);
} }
} }
@ -141,7 +141,7 @@ STATIC void gs2_hmsb_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w,
// Functions for GS4_HMSB format // Functions for GS4_HMSB format
STATIC void gs4_hmsb_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) { STATIC void gs4_hmsb_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) {
uint8_t *pixel = &((uint8_t*)fb->buf)[(x + y * fb->stride) >> 1]; uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1];
if (x % 2) { if (x % 2) {
*pixel = ((uint8_t)col & 0x0f) | (*pixel & 0xf0); *pixel = ((uint8_t)col & 0x0f) | (*pixel & 0xf0);
@ -152,15 +152,15 @@ STATIC void gs4_hmsb_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_
STATIC uint32_t gs4_hmsb_getpixel(const mp_obj_framebuf_t *fb, int x, int y) { STATIC uint32_t gs4_hmsb_getpixel(const mp_obj_framebuf_t *fb, int x, int y) {
if (x % 2) { if (x % 2) {
return ((uint8_t*)fb->buf)[(x + y * fb->stride) >> 1] & 0x0f; return ((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1] & 0x0f;
} }
return ((uint8_t*)fb->buf)[(x + y * fb->stride) >> 1] >> 4; return ((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1] >> 4;
} }
STATIC void gs4_hmsb_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) { STATIC void gs4_hmsb_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) {
col &= 0x0f; col &= 0x0f;
uint8_t *pixel_pair = &((uint8_t*)fb->buf)[(x + y * fb->stride) >> 1]; uint8_t *pixel_pair = &((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1];
uint8_t col_shifted_left = col << 4; uint8_t col_shifted_left = col << 4;
uint8_t col_pixel_pair = col_shifted_left | col; uint8_t col_pixel_pair = col_shifted_left | col;
int pixel_count_till_next_line = (fb->stride - w) >> 1; int pixel_count_till_next_line = (fb->stride - w) >> 1;
@ -192,16 +192,16 @@ STATIC void gs4_hmsb_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w,
// Functions for GS8 format // Functions for GS8 format
STATIC void gs8_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) { STATIC void gs8_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) {
uint8_t *pixel = &((uint8_t*)fb->buf)[(x + y * fb->stride)]; uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride)];
*pixel = col & 0xff; *pixel = col & 0xff;
} }
STATIC uint32_t gs8_getpixel(const mp_obj_framebuf_t *fb, int x, int y) { STATIC uint32_t gs8_getpixel(const mp_obj_framebuf_t *fb, int x, int y) {
return ((uint8_t*)fb->buf)[(x + y * fb->stride)]; return ((uint8_t *)fb->buf)[(x + y * fb->stride)];
} }
STATIC void gs8_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) { STATIC void gs8_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) {
uint8_t *pixel = &((uint8_t*)fb->buf)[(x + y * fb->stride)]; uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride)];
while (h--) { while (h--) {
memset(pixel, col, w); memset(pixel, col, w);
pixel += fb->stride; pixel += fb->stride;
@ -287,7 +287,7 @@ STATIC mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, cons
STATIC const mp_obj_type_t mp_type_framebuf; STATIC const mp_obj_type_t mp_type_framebuf;
// Helper to ensure we have the native super class instead of a subclass. // Helper to ensure we have the native super class instead of a subclass.
static mp_obj_framebuf_t* native_framebuf(mp_obj_t framebuf_obj) { static mp_obj_framebuf_t *native_framebuf(mp_obj_t framebuf_obj) {
mp_obj_t native_framebuf = mp_instance_cast_to_native_base(framebuf_obj, &mp_type_framebuf); mp_obj_t native_framebuf = mp_instance_cast_to_native_base(framebuf_obj, &mp_type_framebuf);
mp_obj_assert_native_inited(native_framebuf); mp_obj_assert_native_inited(native_framebuf);
return MP_OBJ_TO_PTR(native_framebuf); return MP_OBJ_TO_PTR(native_framebuf);
@ -384,9 +384,9 @@ STATIC mp_obj_t framebuf_rect(size_t n_args, const mp_obj_t *args) {
mp_int_t col = mp_obj_get_int(args[5]); mp_int_t col = mp_obj_get_int(args[5]);
fill_rect(self, x, y, w, 1, col); fill_rect(self, x, y, w, 1, col);
fill_rect(self, x, y + h- 1, w, 1, col); fill_rect(self, x, y + h - 1, w, 1, col);
fill_rect(self, x, y, 1, h, col); fill_rect(self, x, y, 1, h, col);
fill_rect(self, x + w- 1, y, 1, h, col); fill_rect(self, x + w - 1, y, 1, h, col);
return mp_const_none; return mp_const_none;
} }
@ -423,9 +423,15 @@ STATIC mp_obj_t framebuf_line(size_t n_args, const mp_obj_t *args) {
bool steep; bool steep;
if (dy > dx) { if (dy > dx) {
mp_int_t temp; mp_int_t temp;
temp = x1; x1 = y1; y1 = temp; temp = x1;
temp = dx; dx = dy; dy = temp; x1 = y1;
temp = sx; sx = sy; sy = temp; y1 = temp;
temp = dx;
dx = dy;
dy = temp;
temp = sx;
sx = sy;
sy = temp;
steep = true; steep = true;
} else { } else {
steep = false; steep = false;
@ -473,7 +479,7 @@ STATIC mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args) {
(y >= self->height) || (y >= self->height) ||
(-x >= source->width) || (-x >= source->width) ||
(-y >= source->height) (-y >= source->height)
) { ) {
// Out of bounds, no-op. // Out of bounds, no-op.
return mp_const_none; return mp_const_none;
} }
@ -547,7 +553,7 @@ STATIC mp_obj_t framebuf_text(size_t n_args, const mp_obj_t *args) {
// loop over chars // loop over chars
for (; *str; ++str) { for (; *str; ++str) {
// get char and make sure its in range of font // get char and make sure its in range of font
int chr = *(uint8_t*)str; int chr = *(uint8_t *)str;
if (chr < 32 || chr > 127) { if (chr < 32 || chr > 127) {
chr = 127; chr = 127;
} }
@ -590,7 +596,7 @@ STATIC const mp_obj_type_t mp_type_framebuf = {
.name = MP_QSTR_FrameBuffer, .name = MP_QSTR_FrameBuffer,
.make_new = framebuf_make_new, .make_new = framebuf_make_new,
.buffer_p = { .get_buffer = framebuf_get_buffer }, .buffer_p = { .get_buffer = framebuf_get_buffer },
.locals_dict = (mp_obj_dict_t*)&framebuf_locals_dict, .locals_dict = (mp_obj_dict_t *)&framebuf_locals_dict,
}; };
// this factory function is provided for backwards compatibility with old FrameBuffer1 class // this factory function is provided for backwards compatibility with old FrameBuffer1 class
@ -633,7 +639,7 @@ STATIC MP_DEFINE_CONST_DICT(framebuf_module_globals, framebuf_module_globals_tab
const mp_obj_module_t mp_module_framebuf = { const mp_obj_module_t mp_module_framebuf = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&framebuf_module_globals, .globals = (mp_obj_dict_t *)&framebuf_module_globals,
}; };
#endif // MICROPY_PY_FRAMEBUF #endif // MICROPY_PY_FRAMEBUF

File diff suppressed because it is too large Load diff

View file

@ -13,8 +13,8 @@
// Low-level 1-Wire routines // Low-level 1-Wire routines
#define TIMING_RESET1 (480) #define TIMING_RESET1 (480)
#define TIMING_RESET2 (40) #define TIMING_RESET2 (70)
#define TIMING_RESET3 (420) #define TIMING_RESET3 (410)
#define TIMING_READ1 (5) #define TIMING_READ1 (5)
#define TIMING_READ2 (5) #define TIMING_READ2 (5)
#define TIMING_READ3 (40) #define TIMING_READ3 (40)
@ -105,7 +105,7 @@ STATIC mp_obj_t onewire_crc8(mp_obj_t data) {
mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ); mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
uint8_t crc = 0; uint8_t crc = 0;
for (size_t i = 0; i < bufinfo.len; ++i) { for (size_t i = 0; i < bufinfo.len; ++i) {
uint8_t byte = ((uint8_t*)bufinfo.buf)[i]; uint8_t byte = ((uint8_t *)bufinfo.buf)[i];
for (int b = 0; b < 8; ++b) { for (int b = 0; b < 8; ++b) {
uint8_t fb_bit = (crc ^ byte) & 0x01; uint8_t fb_bit = (crc ^ byte) & 0x01;
if (fb_bit == 0x01) { if (fb_bit == 0x01) {
@ -137,5 +137,5 @@ STATIC MP_DEFINE_CONST_DICT(onewire_module_globals, onewire_module_globals_table
const mp_obj_module_t mp_module_onewire = { const mp_obj_module_t mp_module_onewire = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&onewire_module_globals, .globals = (mp_obj_dict_t *)&onewire_module_globals,
}; };

View file

@ -12,11 +12,11 @@
#include "extmod/modubinascii.h" #include "extmod/modubinascii.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)) {
mp_raise_TypeError(translate("a bytes-like object is required")); mp_raise_TypeError(translate("a bytes-like object is required"));
} }
#endif #endif
} }
mp_obj_t mod_binascii_hexlify(size_t n_args, const mp_obj_t *args) { mp_obj_t mod_binascii_hexlify(size_t n_args, const mp_obj_t *args) {
@ -41,7 +41,7 @@ mp_obj_t mod_binascii_hexlify(size_t n_args, const mp_obj_t *args) {
sep = mp_obj_str_get_str(args[1]); sep = mp_obj_str_get_str(args[1]);
} }
vstr_init_len(&vstr, out_len); vstr_init_len(&vstr, out_len);
byte *in = bufinfo.buf, *out = (byte*)vstr.buf; byte *in = bufinfo.buf, *out = (byte *)vstr.buf;
for (mp_uint_t i = bufinfo.len; i--;) { for (mp_uint_t i = bufinfo.len; i--;) {
byte d = (*in >> 4); byte d = (*in >> 4);
if (d > 9) { if (d > 9) {
@ -70,7 +70,7 @@ mp_obj_t mod_binascii_unhexlify(mp_obj_t data) {
} }
vstr_t vstr; vstr_t vstr;
vstr_init_len(&vstr, bufinfo.len / 2); vstr_init_len(&vstr, bufinfo.len / 2);
byte *in = bufinfo.buf, *out = (byte*)vstr.buf; byte *in = bufinfo.buf, *out = (byte *)vstr.buf;
byte hex_byte = 0; byte hex_byte = 0;
for (mp_uint_t i = bufinfo.len; i--;) { for (mp_uint_t i = bufinfo.len; i--;) {
byte hex_ch = *in++; byte hex_ch = *in++;
@ -161,7 +161,7 @@ mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) {
vstr_init_len(&vstr, ((bufinfo.len != 0) ? (((bufinfo.len - 1) / 3) + 1) * 4 : 0) + 1); vstr_init_len(&vstr, ((bufinfo.len != 0) ? (((bufinfo.len - 1) / 3) + 1) * 4 : 0) + 1);
// First pass, we convert input buffer to numeric base 64 values // First pass, we convert input buffer to numeric base 64 values
byte *in = bufinfo.buf, *out = (byte*)vstr.buf; byte *in = bufinfo.buf, *out = (byte *)vstr.buf;
mp_uint_t i; mp_uint_t i;
for (i = bufinfo.len; i >= 3; i -= 3) { for (i = bufinfo.len; i >= 3; i -= 3) {
*out++ = (in[0] & 0xFC) >> 2; *out++ = (in[0] & 0xFC) >> 2;
@ -175,8 +175,7 @@ mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) {
if (i == 2) { if (i == 2) {
*out++ = (in[0] & 0x03) << 4 | (in[1] & 0xF0) >> 4; *out++ = (in[0] & 0x03) << 4 | (in[1] & 0xF0) >> 4;
*out++ = (in[1] & 0x0F) << 2; *out++ = (in[1] & 0x0F) << 2;
} } else {
else {
*out++ = (in[0] & 0x03) << 4; *out++ = (in[0] & 0x03) << 4;
*out++ = 64; *out++ = 64;
} }
@ -184,7 +183,7 @@ mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) {
} }
// Second pass, we convert number base 64 values to actual base64 ascii encoding // Second pass, we convert number base 64 values to actual base64 ascii encoding
out = (byte*)vstr.buf; out = (byte *)vstr.buf;
for (mp_uint_t j = vstr.len - 1; j--;) { for (mp_uint_t j = vstr.len - 1; j--;) {
if (*out < 26) { if (*out < 26) {
*out += 'A'; *out += 'A';
@ -193,7 +192,7 @@ mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) {
} else if (*out < 62) { } else if (*out < 62) {
*out += '0' - 52; *out += '0' - 52;
} else if (*out == 62) { } else if (*out == 62) {
*out ='+'; *out = '+';
} else if (*out == 63) { } else if (*out == 63) {
*out = '/'; *out = '/';
} else { } else {
@ -237,7 +236,7 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_binascii_globals, mp_module_binascii_globa
const mp_obj_module_t mp_module_ubinascii = { const mp_obj_module_t mp_module_ubinascii = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_binascii_globals, .globals = (mp_obj_dict_t *)&mp_module_binascii_globals,
}; };
#endif //MICROPY_PY_UBINASCII #endif // MICROPY_PY_UBINASCII

View file

@ -1,4 +1,4 @@
// Copyright (c) 2014 Paul Sokolovsky // Copyright (c) 2014-2018 Paul Sokolovsky
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) // SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
@ -73,7 +73,7 @@ enum {
#define AGG_TYPE_BITS 2 #define AGG_TYPE_BITS 2
enum { enum {
STRUCT, PTR, ARRAY, BITFIELD, STRUCT, PTR, ARRAY,
}; };
// Here we need to set sign bit right // Here we need to set sign bit right
@ -105,7 +105,7 @@ STATIC mp_obj_t uctypes_struct_make_new(const mp_obj_type_t *type, size_t n_args
mp_arg_check_num(n_args, kw_args, 2, 3, false); mp_arg_check_num(n_args, kw_args, 2, 3, false);
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t); mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t);
o->base.type = type; o->base.type = type;
o->addr = (void*)(uintptr_t)mp_obj_int_get_truncated(args[0]); o->addr = (void *)(uintptr_t)mp_obj_int_get_truncated(args[0]);
o->desc = args[1]; o->desc = args[1];
o->flags = LAYOUT_NATIVE; o->flags = LAYOUT_NATIVE;
if (n_args == 3) { if (n_args == 3) {
@ -118,15 +118,23 @@ STATIC void uctypes_struct_print(const mp_print_t *print, mp_obj_t self_in, mp_p
(void)kind; (void)kind;
mp_obj_uctypes_struct_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_uctypes_struct_t *self = MP_OBJ_TO_PTR(self_in);
const char *typen = "unk"; const char *typen = "unk";
if (MP_OBJ_IS_TYPE(self->desc, &mp_type_dict)) { if (MP_OBJ_IS_TYPE(self->desc, &mp_type_dict)
#if MICROPY_PY_COLLECTIONS_ORDEREDDICT
|| MP_OBJ_IS_TYPE(self->desc, &mp_type_ordereddict)
#endif
) {
typen = "STRUCT"; typen = "STRUCT";
} else if (MP_OBJ_IS_TYPE(self->desc, &mp_type_tuple)) { } else if (MP_OBJ_IS_TYPE(self->desc, &mp_type_tuple)) {
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(self->desc); mp_obj_tuple_t *t = MP_OBJ_TO_PTR(self->desc);
mp_int_t offset = MP_OBJ_SMALL_INT_VALUE(t->items[0]); mp_int_t offset = MP_OBJ_SMALL_INT_VALUE(t->items[0]);
uint agg_type = GET_TYPE(offset, AGG_TYPE_BITS); uint agg_type = GET_TYPE(offset, AGG_TYPE_BITS);
switch (agg_type) { switch (agg_type) {
case PTR: typen = "PTR"; break; case PTR:
case ARRAY: typen = "ARRAY"; break; typen = "PTR";
break;
case ARRAY:
typen = "ARRAY";
break;
} }
} else { } else {
typen = "ERROR"; typen = "ERROR";
@ -157,10 +165,10 @@ STATIC mp_uint_t uctypes_struct_agg_size(mp_obj_tuple_t *t, int layout_type, mp_
case STRUCT: case STRUCT:
return uctypes_struct_size(t->items[1], layout_type, max_field_size); return uctypes_struct_size(t->items[1], layout_type, max_field_size);
case PTR: case PTR:
if (sizeof(void*) > *max_field_size) { if (sizeof(void *) > *max_field_size) {
*max_field_size = sizeof(void*); *max_field_size = sizeof(void *);
} }
return sizeof(void*); return sizeof(void *);
case ARRAY: { case ARRAY: {
mp_int_t arr_sz = MP_OBJ_SMALL_INT_VALUE(t->items[1]); mp_int_t arr_sz = MP_OBJ_SMALL_INT_VALUE(t->items[1]);
uint val_type = GET_TYPE(arr_sz, VAL_TYPE_BITS); uint val_type = GET_TYPE(arr_sz, VAL_TYPE_BITS);
@ -187,9 +195,13 @@ STATIC mp_uint_t uctypes_struct_agg_size(mp_obj_tuple_t *t, int layout_type, mp_
} }
STATIC mp_uint_t uctypes_struct_size(mp_obj_t desc_in, int layout_type, mp_uint_t *max_field_size) { STATIC mp_uint_t uctypes_struct_size(mp_obj_t desc_in, int layout_type, mp_uint_t *max_field_size) {
if (!MP_OBJ_IS_TYPE(desc_in, &mp_type_dict)) { if (!MP_OBJ_IS_TYPE(desc_in, &mp_type_dict)
#if MICROPY_PY_COLLECTIONS_ORDEREDDICT
&& !MP_OBJ_IS_TYPE(desc_in, &mp_type_ordereddict)
#endif
) {
if (MP_OBJ_IS_TYPE(desc_in, &mp_type_tuple)) { if (MP_OBJ_IS_TYPE(desc_in, &mp_type_tuple)) {
return uctypes_struct_agg_size((mp_obj_tuple_t*)MP_OBJ_TO_PTR(desc_in), layout_type, max_field_size); return uctypes_struct_agg_size((mp_obj_tuple_t *)MP_OBJ_TO_PTR(desc_in), layout_type, max_field_size);
} else if (MP_OBJ_IS_SMALL_INT(desc_in)) { } else if (MP_OBJ_IS_SMALL_INT(desc_in)) {
// We allow sizeof on both type definitions and structures/structure fields, // We allow sizeof on both type definitions and structures/structure fields,
// but scalar structure field is lowered into native Python int, so all // but scalar structure field is lowered into native Python int, so all
@ -242,7 +254,8 @@ STATIC mp_uint_t uctypes_struct_size(mp_obj_t desc_in, int layout_type, mp_uint_
return total_size; return total_size;
} }
STATIC mp_obj_t uctypes_struct_sizeof(mp_obj_t obj_in) { STATIC mp_obj_t uctypes_struct_sizeof(size_t n_args, const mp_obj_t *args) {
mp_obj_t obj_in = args[0];
mp_uint_t max_field_size = 0; mp_uint_t max_field_size = 0;
if (MP_OBJ_IS_TYPE(obj_in, &mp_type_bytearray)) { if (MP_OBJ_IS_TYPE(obj_in, &mp_type_bytearray)) {
return mp_obj_len(obj_in); return mp_obj_len(obj_in);
@ -251,15 +264,22 @@ STATIC mp_obj_t uctypes_struct_sizeof(mp_obj_t obj_in) {
// We can apply sizeof either to structure definition (a dict) // We can apply sizeof either to structure definition (a dict)
// or to instantiated structure // or to instantiated structure
if (MP_OBJ_IS_TYPE(obj_in, &uctypes_struct_type)) { if (MP_OBJ_IS_TYPE(obj_in, &uctypes_struct_type)) {
if (n_args != 1) {
mp_raise_TypeError(NULL);
}
// Extract structure definition // Extract structure definition
mp_obj_uctypes_struct_t *obj = MP_OBJ_TO_PTR(obj_in); mp_obj_uctypes_struct_t *obj = MP_OBJ_TO_PTR(obj_in);
obj_in = obj->desc; obj_in = obj->desc;
layout_type = obj->flags; layout_type = obj->flags;
} else {
if (n_args == 2) {
layout_type = mp_obj_get_int(args[1]);
}
} }
mp_uint_t size = uctypes_struct_size(obj_in, layout_type, &max_field_size); mp_uint_t size = uctypes_struct_size(obj_in, layout_type, &max_field_size);
return MP_OBJ_NEW_SMALL_INT(size); return MP_OBJ_NEW_SMALL_INT(size);
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(uctypes_struct_sizeof_obj, uctypes_struct_sizeof); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(uctypes_struct_sizeof_obj, 1, 2, uctypes_struct_sizeof);
static inline mp_obj_t get_unaligned(uint val_type, byte *p, int big_endian) { static inline mp_obj_t get_unaligned(uint val_type, byte *p, int big_endian) {
char struct_type = big_endian ? '>' : '<'; char struct_type = big_endian ? '>' : '<';
@ -276,11 +296,11 @@ static inline void set_unaligned(uint val_type, byte *p, int big_endian, mp_obj_
static inline mp_uint_t get_aligned_basic(uint val_type, void *p) { static inline mp_uint_t get_aligned_basic(uint val_type, void *p) {
switch (val_type) { switch (val_type) {
case UINT8: case UINT8:
return *(uint8_t*)p; return *(uint8_t *)p;
case UINT16: case UINT16:
return *(uint16_t*)p; return *(uint16_t *)p;
case UINT32: case UINT32:
return *(uint32_t*)p; return *(uint32_t *)p;
} }
assert(0); assert(0);
return 0; return 0;
@ -289,11 +309,14 @@ static inline mp_uint_t get_aligned_basic(uint val_type, void *p) {
static inline void set_aligned_basic(uint val_type, void *p, mp_uint_t v) { static inline void set_aligned_basic(uint val_type, void *p, mp_uint_t v) {
switch (val_type) { switch (val_type) {
case UINT8: case UINT8:
*(uint8_t*)p = (uint8_t)v; return; *(uint8_t *)p = (uint8_t)v;
return;
case UINT16: case UINT16:
*(uint16_t*)p = (uint16_t)v; return; *(uint16_t *)p = (uint16_t)v;
return;
case UINT32: case UINT32:
*(uint32_t*)p = (uint32_t)v; return; *(uint32_t *)p = (uint32_t)v;
return;
} }
assert(0); assert(0);
} }
@ -301,26 +324,26 @@ static inline void set_aligned_basic(uint val_type, void *p, mp_uint_t v) {
STATIC mp_obj_t get_aligned(uint val_type, void *p, mp_int_t index) { STATIC mp_obj_t get_aligned(uint val_type, void *p, mp_int_t index) {
switch (val_type) { switch (val_type) {
case UINT8: case UINT8:
return MP_OBJ_NEW_SMALL_INT(((uint8_t*)p)[index]); return MP_OBJ_NEW_SMALL_INT(((uint8_t *)p)[index]);
case INT8: case INT8:
return MP_OBJ_NEW_SMALL_INT(((int8_t*)p)[index]); return MP_OBJ_NEW_SMALL_INT(((int8_t *)p)[index]);
case UINT16: case UINT16:
return MP_OBJ_NEW_SMALL_INT(((uint16_t*)p)[index]); return MP_OBJ_NEW_SMALL_INT(((uint16_t *)p)[index]);
case INT16: case INT16:
return MP_OBJ_NEW_SMALL_INT(((int16_t*)p)[index]); return MP_OBJ_NEW_SMALL_INT(((int16_t *)p)[index]);
case UINT32: case UINT32:
return mp_obj_new_int_from_uint(((uint32_t*)p)[index]); return mp_obj_new_int_from_uint(((uint32_t *)p)[index]);
case INT32: case INT32:
return mp_obj_new_int(((int32_t*)p)[index]); return mp_obj_new_int(((int32_t *)p)[index]);
case UINT64: case UINT64:
return mp_obj_new_int_from_ull(((uint64_t*)p)[index]); return mp_obj_new_int_from_ull(((uint64_t *)p)[index]);
case INT64: case INT64:
return mp_obj_new_int_from_ll(((int64_t*)p)[index]); return mp_obj_new_int_from_ll(((int64_t *)p)[index]);
#if MICROPY_PY_BUILTINS_FLOAT #if MICROPY_PY_BUILTINS_FLOAT
case FLOAT32: case FLOAT32:
return mp_obj_new_float((mp_float_t)((float*)p)[index]); return mp_obj_new_float(((float *)p)[index]);
case FLOAT64: case FLOAT64:
return mp_obj_new_float(((double*)p)[index]); return mp_obj_new_float(((double *)p)[index]);
#endif #endif
default: default:
assert(0); assert(0);
@ -333,9 +356,9 @@ STATIC void set_aligned(uint val_type, void *p, mp_int_t index, mp_obj_t val) {
if (val_type == FLOAT32 || val_type == FLOAT64) { if (val_type == FLOAT32 || val_type == FLOAT64) {
mp_float_t v = mp_obj_get_float(val); mp_float_t v = mp_obj_get_float(val);
if (val_type == FLOAT32) { if (val_type == FLOAT32) {
((float*)p)[index] = v; ((float *)p)[index] = v;
} else { } else {
((double*)p)[index] = v; ((double *)p)[index] = v;
} }
return; return;
} }
@ -343,21 +366,27 @@ STATIC void set_aligned(uint val_type, void *p, mp_int_t index, mp_obj_t val) {
mp_int_t v = mp_obj_get_int_truncated(val); mp_int_t v = mp_obj_get_int_truncated(val);
switch (val_type) { switch (val_type) {
case UINT8: case UINT8:
((uint8_t*)p)[index] = (uint8_t)v; return; ((uint8_t *)p)[index] = (uint8_t)v;
return;
case INT8: case INT8:
((int8_t*)p)[index] = (int8_t)v; return; ((int8_t *)p)[index] = (int8_t)v;
return;
case UINT16: case UINT16:
((uint16_t*)p)[index] = (uint16_t)v; return; ((uint16_t *)p)[index] = (uint16_t)v;
return;
case INT16: case INT16:
((int16_t*)p)[index] = (int16_t)v; return; ((int16_t *)p)[index] = (int16_t)v;
return;
case UINT32: case UINT32:
((uint32_t*)p)[index] = (uint32_t)v; return; ((uint32_t *)p)[index] = (uint32_t)v;
return;
case INT32: case INT32:
((int32_t*)p)[index] = (int32_t)v; return; ((int32_t *)p)[index] = (int32_t)v;
return;
case INT64: case INT64:
case UINT64: case UINT64:
if (sizeof(mp_int_t) == 8) { if (sizeof(mp_int_t) == 8) {
((uint64_t*)p)[index] = (uint64_t)v; ((uint64_t *)p)[index] = (uint64_t)v;
} else { } else {
// TODO: Doesn't offer atomic store semantics, but should at least try // TODO: Doesn't offer atomic store semantics, but should at least try
set_unaligned(val_type, p, MP_ENDIANNESS_BIG, val); set_unaligned(val_type, p, MP_ENDIANNESS_BIG, val);
@ -371,9 +400,12 @@ STATIC void set_aligned(uint val_type, void *p, mp_int_t index, mp_obj_t val) {
STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set_val) { STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set_val) {
mp_obj_uctypes_struct_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_uctypes_struct_t *self = MP_OBJ_TO_PTR(self_in);
// TODO: Support at least OrderedDict in addition if (!MP_OBJ_IS_TYPE(self->desc, &mp_type_dict)
if (!MP_OBJ_IS_TYPE(self->desc, &mp_type_dict)) { #if MICROPY_PY_COLLECTIONS_ORDEREDDICT
mp_raise_TypeError(translate("struct: no fields")); && !MP_OBJ_IS_TYPE(self->desc, &mp_type_ordereddict)
#endif
) {
mp_raise_TypeError(translate("struct: no fields"));
} }
mp_obj_t deref = mp_obj_dict_get(self->desc, MP_OBJ_NEW_QSTR(attr)); mp_obj_t deref = mp_obj_dict_get(self->desc, MP_OBJ_NEW_QSTR(attr));
@ -381,7 +413,7 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set
mp_int_t offset = MP_OBJ_SMALL_INT_VALUE(deref); mp_int_t offset = MP_OBJ_SMALL_INT_VALUE(deref);
mp_uint_t val_type = GET_TYPE(offset, VAL_TYPE_BITS); mp_uint_t val_type = GET_TYPE(offset, VAL_TYPE_BITS);
offset &= VALUE_MASK(VAL_TYPE_BITS); offset &= VALUE_MASK(VAL_TYPE_BITS);
//printf("scalar type=%d offset=%x\n", val_type, offset); // printf("scalar type=%d offset=%x\n", val_type, offset);
if (val_type <= INT64 || val_type == FLOAT32 || val_type == FLOAT64) { if (val_type <= INT64 || val_type == FLOAT32 || val_type == FLOAT64) {
// printf("size=%d\n", GET_SCALAR_SIZE(val_type)); // printf("size=%d\n", GET_SCALAR_SIZE(val_type));
@ -451,7 +483,7 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set
mp_int_t offset = MP_OBJ_SMALL_INT_VALUE(sub->items[0]); mp_int_t offset = MP_OBJ_SMALL_INT_VALUE(sub->items[0]);
mp_uint_t agg_type = GET_TYPE(offset, AGG_TYPE_BITS); mp_uint_t agg_type = GET_TYPE(offset, AGG_TYPE_BITS);
offset &= VALUE_MASK(AGG_TYPE_BITS); offset &= VALUE_MASK(AGG_TYPE_BITS);
//printf("agg type=%d offset=%x\n", agg_type, offset); // printf("agg type=%d offset=%x\n", agg_type, offset);
switch (agg_type) { switch (agg_type) {
case STRUCT: { case STRUCT: {
@ -475,7 +507,7 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set
o->desc = MP_OBJ_FROM_PTR(sub); o->desc = MP_OBJ_FROM_PTR(sub);
o->addr = self->addr + offset; o->addr = self->addr + offset;
o->flags = self->flags; o->flags = self->flags;
//printf("PTR/ARR base addr=%p\n", o->addr); // printf("PTR/ARR base addr=%p\n", o->addr);
return MP_OBJ_FROM_PTR(o); return MP_OBJ_FROM_PTR(o);
} }
} }
@ -555,7 +587,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t base_in, mp_obj_t index_in, mp_ob
} }
} else if (agg_type == PTR) { } else if (agg_type == PTR) {
byte *p = *(void**)self->addr; byte *p = *(void **)self->addr;
if (MP_OBJ_IS_SMALL_INT(t->items[1])) { if (MP_OBJ_IS_SMALL_INT(t->items[1])) {
uint val_type = GET_TYPE(MP_OBJ_SMALL_INT_VALUE(t->items[1]), VAL_TYPE_BITS); uint val_type = GET_TYPE(MP_OBJ_SMALL_INT_VALUE(t->items[1]), VAL_TYPE_BITS);
return get_aligned(val_type, p, index); return get_aligned(val_type, p, index);
@ -576,6 +608,26 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t base_in, mp_obj_t index_in, mp_ob
} }
} }
STATIC mp_obj_t uctypes_struct_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
mp_obj_uctypes_struct_t *self = MP_OBJ_TO_PTR(self_in);
switch (op) {
case MP_UNARY_OP_INT:
if (MP_OBJ_IS_TYPE(self->desc, &mp_type_tuple)) {
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(self->desc);
mp_int_t offset = MP_OBJ_SMALL_INT_VALUE(t->items[0]);
uint agg_type = GET_TYPE(offset, AGG_TYPE_BITS);
if (agg_type == PTR) {
byte *p = *(void **)self->addr;
return mp_obj_new_int((mp_int_t)(uintptr_t)p);
}
}
/* fallthru */
default:
return MP_OBJ_NULL; // op not supported
}
}
STATIC mp_int_t uctypes_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { STATIC mp_int_t uctypes_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
(void)flags; (void)flags;
mp_obj_uctypes_struct_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_uctypes_struct_t *self = MP_OBJ_TO_PTR(self_in);
@ -603,7 +655,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(uctypes_struct_addressof_obj, uctypes_struct_addressof
/// captured by reference (and thus memory pointed by bytearray may change /// captured by reference (and thus memory pointed by bytearray may change
/// or become invalid at later time). Use bytes_at() to capture by value. /// or become invalid at later time). Use bytes_at() to capture by value.
STATIC mp_obj_t uctypes_struct_bytearray_at(mp_obj_t ptr, mp_obj_t size) { STATIC mp_obj_t uctypes_struct_bytearray_at(mp_obj_t ptr, mp_obj_t size) {
return mp_obj_new_bytearray_by_ref(mp_obj_int_get_truncated(size), (void*)(uintptr_t)mp_obj_int_get_truncated(ptr)); return mp_obj_new_bytearray_by_ref(mp_obj_int_get_truncated(size), (void *)(uintptr_t)mp_obj_int_get_truncated(ptr));
} }
MP_DEFINE_CONST_FUN_OBJ_2(uctypes_struct_bytearray_at_obj, uctypes_struct_bytearray_at); MP_DEFINE_CONST_FUN_OBJ_2(uctypes_struct_bytearray_at_obj, uctypes_struct_bytearray_at);
@ -612,7 +664,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(uctypes_struct_bytearray_at_obj, uctypes_struct_bytear
/// captured by value, i.e. copied. Use bytearray_at() to capture by reference /// captured by value, i.e. copied. Use bytearray_at() to capture by reference
/// ("zero copy"). /// ("zero copy").
STATIC mp_obj_t uctypes_struct_bytes_at(mp_obj_t ptr, mp_obj_t size) { STATIC mp_obj_t uctypes_struct_bytes_at(mp_obj_t ptr, mp_obj_t size) {
return mp_obj_new_bytes((void*)(uintptr_t)mp_obj_int_get_truncated(ptr), mp_obj_int_get_truncated(size)); return mp_obj_new_bytes((void *)(uintptr_t)mp_obj_int_get_truncated(ptr), mp_obj_int_get_truncated(size));
} }
MP_DEFINE_CONST_FUN_OBJ_2(uctypes_struct_bytes_at_obj, uctypes_struct_bytes_at); MP_DEFINE_CONST_FUN_OBJ_2(uctypes_struct_bytes_at_obj, uctypes_struct_bytes_at);
@ -624,6 +676,7 @@ STATIC const mp_obj_type_t uctypes_struct_type = {
.make_new = uctypes_struct_make_new, .make_new = uctypes_struct_make_new,
.attr = uctypes_struct_attr, .attr = uctypes_struct_attr,
.subscr = uctypes_struct_subscr, .subscr = uctypes_struct_subscr,
.unary_op = uctypes_struct_unary_op,
.buffer_p = { .get_buffer = uctypes_get_buffer }, .buffer_p = { .get_buffer = uctypes_get_buffer },
}; };
@ -682,6 +735,30 @@ STATIC const mp_rom_map_elem_t mp_module_uctypes_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_FLOAT64), MP_ROM_INT(TYPE2SMALLINT(FLOAT64, 4)) }, { MP_ROM_QSTR(MP_QSTR_FLOAT64), MP_ROM_INT(TYPE2SMALLINT(FLOAT64, 4)) },
#endif #endif
#if MICROPY_PY_UCTYPES_NATIVE_C_TYPES
// C native type aliases. These depend on GCC-compatible predefined
// preprocessor macros.
#if __SIZEOF_SHORT__ == 2
{ MP_ROM_QSTR(MP_QSTR_SHORT), MP_ROM_INT(TYPE2SMALLINT(INT16, 4)) },
{ MP_ROM_QSTR(MP_QSTR_USHORT), MP_ROM_INT(TYPE2SMALLINT(UINT16, 4)) },
#endif
#if __SIZEOF_INT__ == 4
{ MP_ROM_QSTR(MP_QSTR_INT), MP_ROM_INT(TYPE2SMALLINT(INT32, 4)) },
{ MP_ROM_QSTR(MP_QSTR_UINT), MP_ROM_INT(TYPE2SMALLINT(UINT32, 4)) },
#endif
#if __SIZEOF_LONG__ == 4
{ MP_ROM_QSTR(MP_QSTR_LONG), MP_ROM_INT(TYPE2SMALLINT(INT32, 4)) },
{ MP_ROM_QSTR(MP_QSTR_ULONG), MP_ROM_INT(TYPE2SMALLINT(UINT32, 4)) },
#elif __SIZEOF_LONG__ == 8
{ MP_ROM_QSTR(MP_QSTR_LONG), MP_ROM_INT(TYPE2SMALLINT(INT64, 4)) },
{ MP_ROM_QSTR(MP_QSTR_ULONG), MP_ROM_INT(TYPE2SMALLINT(UINT64, 4)) },
#endif
#if __SIZEOF_LONG_LONG__ == 8
{ MP_ROM_QSTR(MP_QSTR_LONGLONG), MP_ROM_INT(TYPE2SMALLINT(INT64, 4)) },
{ MP_ROM_QSTR(MP_QSTR_ULONGLONG), MP_ROM_INT(TYPE2SMALLINT(UINT64, 4)) },
#endif
#endif // MICROPY_PY_UCTYPES_NATIVE_C_TYPES
{ MP_ROM_QSTR(MP_QSTR_PTR), MP_ROM_INT(TYPE2SMALLINT(PTR, AGG_TYPE_BITS)) }, { MP_ROM_QSTR(MP_QSTR_PTR), MP_ROM_INT(TYPE2SMALLINT(PTR, AGG_TYPE_BITS)) },
{ MP_ROM_QSTR(MP_QSTR_ARRAY), MP_ROM_INT(TYPE2SMALLINT(ARRAY, AGG_TYPE_BITS)) }, { MP_ROM_QSTR(MP_QSTR_ARRAY), MP_ROM_INT(TYPE2SMALLINT(ARRAY, AGG_TYPE_BITS)) },
}; };
@ -690,7 +767,7 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_uctypes_globals, mp_module_uctypes_globals
const mp_obj_module_t mp_module_uctypes = { const mp_obj_module_t mp_module_uctypes = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_uctypes_globals, .globals = (mp_obj_dict_t *)&mp_module_uctypes_globals,
}; };
#endif #endif

View file

@ -12,6 +12,10 @@
#if MICROPY_PY_UHASHLIB #if MICROPY_PY_UHASHLIB
#if MICROPY_SSL_MBEDTLS
#include "mbedtls/version.h"
#endif
#if MICROPY_PY_UHASHLIB_SHA256 #if MICROPY_PY_UHASHLIB_SHA256
#if MICROPY_SSL_MBEDTLS #if MICROPY_SSL_MBEDTLS
@ -22,13 +26,14 @@
#endif #endif
#if MICROPY_PY_UHASHLIB_SHA1 #if MICROPY_PY_UHASHLIB_SHA1 || MICROPY_PY_UHASHLIB_MD5
#if MICROPY_SSL_AXTLS #if MICROPY_SSL_AXTLS
#include "lib/axtls/crypto/crypto.h" #include "lib/axtls/crypto/crypto.h"
#endif #endif
#if MICROPY_SSL_MBEDTLS #if MICROPY_SSL_MBEDTLS
#include "mbedtls/md5.h"
#include "mbedtls/sha1.h" #include "mbedtls/sha1.h"
#endif #endif
@ -45,12 +50,18 @@ STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg);
#if MICROPY_SSL_MBEDTLS #if MICROPY_SSL_MBEDTLS
STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { #if MBEDTLS_VERSION_NUMBER < 0x02070000
mp_arg_check_num(n_args, kw_args, 0, 1, false); #define mbedtls_sha256_starts_ret mbedtls_sha256_starts
#define mbedtls_sha256_update_ret mbedtls_sha256_update
#define mbedtls_sha256_finish_ret mbedtls_sha256_finish
#endif
STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha256_context)); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha256_context));
o->base.type = type; o->base.type = type;
mbedtls_sha256_init((mbedtls_sha256_context*)&o->state); mbedtls_sha256_init((mbedtls_sha256_context *)&o->state);
mbedtls_sha256_starts((mbedtls_sha256_context*)&o->state, 0); mbedtls_sha256_starts_ret((mbedtls_sha256_context *)&o->state, 0);
if (n_args == 1) { if (n_args == 1) {
uhashlib_sha256_update(MP_OBJ_FROM_PTR(o), args[0]); uhashlib_sha256_update(MP_OBJ_FROM_PTR(o), args[0]);
} }
@ -61,7 +72,7 @@ STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ);
mbedtls_sha256_update((mbedtls_sha256_context*)&self->state, bufinfo.buf, bufinfo.len); mbedtls_sha256_update_ret((mbedtls_sha256_context *)&self->state, bufinfo.buf, bufinfo.len);
return mp_const_none; return mp_const_none;
} }
@ -69,25 +80,25 @@ STATIC mp_obj_t uhashlib_sha256_digest(mp_obj_t self_in) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
vstr_t vstr; vstr_t vstr;
vstr_init_len(&vstr, 32); vstr_init_len(&vstr, 32);
mbedtls_sha256_finish((mbedtls_sha256_context*)&self->state, (unsigned char *)vstr.buf); mbedtls_sha256_finish_ret((mbedtls_sha256_context *)&self->state, (unsigned char *)vstr.buf);
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
} }
#else #else
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)) {
mp_raise_TypeError(translate("a bytes-like object is required")); mp_raise_TypeError(translate("a bytes-like object is required"));
} }
#endif #endif
} }
STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
mp_arg_check_num(n_args, kw_args, 0, 1, false); mp_arg_check_num(n_args, kw_args, 0, 1, false);
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX)); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX));
o->base.type = type; o->base.type = type;
sha256_init((CRYAL_SHA256_CTX*)o->state); sha256_init((CRYAL_SHA256_CTX *)o->state);
if (n_args == 1) { if (n_args == 1) {
uhashlib_sha256_update(MP_OBJ_FROM_PTR(o), args[0]); uhashlib_sha256_update(MP_OBJ_FROM_PTR(o), args[0]);
} }
@ -99,7 +110,7 @@ STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ);
sha256_update((CRYAL_SHA256_CTX*)self->state, bufinfo.buf, bufinfo.len); sha256_update((CRYAL_SHA256_CTX *)self->state, bufinfo.buf, bufinfo.len);
return mp_const_none; return mp_const_none;
} }
@ -107,7 +118,7 @@ STATIC mp_obj_t uhashlib_sha256_digest(mp_obj_t self_in) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
vstr_t vstr; vstr_t vstr;
vstr_init_len(&vstr, SHA256_BLOCK_SIZE); vstr_init_len(&vstr, SHA256_BLOCK_SIZE);
sha256_final((CRYAL_SHA256_CTX*)self->state, (byte*)vstr.buf); sha256_final((CRYAL_SHA256_CTX *)self->state, (byte *)vstr.buf);
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
} }
#endif #endif
@ -126,7 +137,7 @@ STATIC const mp_obj_type_t uhashlib_sha256_type = {
{ &mp_type_type }, { &mp_type_type },
.name = MP_QSTR_sha256, .name = MP_QSTR_sha256,
.make_new = uhashlib_sha256_make_new, .make_new = uhashlib_sha256_make_new,
.locals_dict = (void*)&uhashlib_sha256_locals_dict, .locals_dict = (void *)&uhashlib_sha256_locals_dict,
}; };
#endif #endif
@ -138,7 +149,7 @@ STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args,
mp_arg_check_num(n_args, kw_args, 0, 1, false); mp_arg_check_num(n_args, kw_args, 0, 1, false);
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(SHA1_CTX)); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(SHA1_CTX));
o->base.type = type; o->base.type = type;
SHA1_Init((SHA1_CTX*)o->state); SHA1_Init((SHA1_CTX *)o->state);
if (n_args == 1) { if (n_args == 1) {
uhashlib_sha1_update(MP_OBJ_FROM_PTR(o), args[0]); uhashlib_sha1_update(MP_OBJ_FROM_PTR(o), args[0]);
} }
@ -150,7 +161,7 @@ STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ);
SHA1_Update((SHA1_CTX*)self->state, bufinfo.buf, bufinfo.len); SHA1_Update((SHA1_CTX *)self->state, bufinfo.buf, bufinfo.len);
return mp_const_none; return mp_const_none;
} }
@ -158,18 +169,25 @@ STATIC mp_obj_t uhashlib_sha1_digest(mp_obj_t self_in) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
vstr_t vstr; vstr_t vstr;
vstr_init_len(&vstr, SHA1_SIZE); vstr_init_len(&vstr, SHA1_SIZE);
SHA1_Final((byte*)vstr.buf, (SHA1_CTX*)self->state); SHA1_Final((byte *)vstr.buf, (SHA1_CTX *)self->state);
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
} }
#endif #endif
#if MICROPY_SSL_MBEDTLS #if MICROPY_SSL_MBEDTLS
#if MBEDTLS_VERSION_NUMBER < 0x02070000
#define mbedtls_sha1_starts_ret mbedtls_sha1_starts
#define mbedtls_sha1_update_ret mbedtls_sha1_update
#define mbedtls_sha1_finish_ret mbedtls_sha1_finish
#endif
STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha1_context)); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha1_context));
o->base.type = type; o->base.type = type;
mbedtls_sha1_init((mbedtls_sha1_context*)o->state); mbedtls_sha1_init((mbedtls_sha1_context *)o->state);
mbedtls_sha1_starts((mbedtls_sha1_context*)o->state); mbedtls_sha1_starts_ret((mbedtls_sha1_context *)o->state);
if (n_args == 1) { if (n_args == 1) {
uhashlib_sha1_update(MP_OBJ_FROM_PTR(o), args[0]); uhashlib_sha1_update(MP_OBJ_FROM_PTR(o), args[0]);
} }
@ -180,7 +198,7 @@ STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ);
mbedtls_sha1_update((mbedtls_sha1_context*)self->state, bufinfo.buf, bufinfo.len); mbedtls_sha1_update_ret((mbedtls_sha1_context *)self->state, bufinfo.buf, bufinfo.len);
return mp_const_none; return mp_const_none;
} }
@ -188,8 +206,8 @@ STATIC mp_obj_t uhashlib_sha1_digest(mp_obj_t self_in) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
vstr_t vstr; vstr_t vstr;
vstr_init_len(&vstr, 20); vstr_init_len(&vstr, 20);
mbedtls_sha1_finish((mbedtls_sha1_context*)self->state, (byte*)vstr.buf); mbedtls_sha1_finish_ret((mbedtls_sha1_context *)self->state, (byte *)vstr.buf);
mbedtls_sha1_free((mbedtls_sha1_context*)self->state); mbedtls_sha1_free((mbedtls_sha1_context *)self->state);
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
} }
#endif #endif
@ -207,10 +225,97 @@ STATIC const mp_obj_type_t uhashlib_sha1_type = {
{ &mp_type_type }, { &mp_type_type },
.name = MP_QSTR_sha1, .name = MP_QSTR_sha1,
.make_new = uhashlib_sha1_make_new, .make_new = uhashlib_sha1_make_new,
.locals_dict = (void*)&uhashlib_sha1_locals_dict, .locals_dict = (void *)&uhashlib_sha1_locals_dict,
}; };
#endif #endif
#if MICROPY_PY_UHASHLIB_MD5
STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg);
#if MICROPY_SSL_AXTLS
STATIC mp_obj_t uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(MD5_CTX));
o->base.type = type;
MD5_Init((MD5_CTX *)o->state);
if (n_args == 1) {
uhashlib_md5_update(MP_OBJ_FROM_PTR(o), args[0]);
}
return MP_OBJ_FROM_PTR(o);
}
STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ);
MD5_Update((MD5_CTX *)self->state, bufinfo.buf, bufinfo.len);
return mp_const_none;
}
STATIC mp_obj_t uhashlib_md5_digest(mp_obj_t self_in) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
vstr_t vstr;
vstr_init_len(&vstr, MD5_SIZE);
MD5_Final((byte *)vstr.buf, (MD5_CTX *)self->state);
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
#endif // MICROPY_SSL_AXTLS
#if MICROPY_SSL_MBEDTLS
#if MBEDTLS_VERSION_NUMBER < 0x02070000
#define mbedtls_md5_starts_ret mbedtls_md5_starts
#define mbedtls_md5_update_ret mbedtls_md5_update
#define mbedtls_md5_finish_ret mbedtls_md5_finish
#endif
STATIC mp_obj_t uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_md5_context));
o->base.type = type;
mbedtls_md5_init((mbedtls_md5_context *)o->state);
mbedtls_md5_starts_ret((mbedtls_md5_context *)o->state);
if (n_args == 1) {
uhashlib_md5_update(MP_OBJ_FROM_PTR(o), args[0]);
}
return MP_OBJ_FROM_PTR(o);
}
STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ);
mbedtls_md5_update_ret((mbedtls_md5_context *)self->state, bufinfo.buf, bufinfo.len);
return mp_const_none;
}
STATIC mp_obj_t uhashlib_md5_digest(mp_obj_t self_in) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
vstr_t vstr;
vstr_init_len(&vstr, 16);
mbedtls_md5_finish_ret((mbedtls_md5_context *)self->state, (byte *)vstr.buf);
mbedtls_md5_free((mbedtls_md5_context *)self->state);
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
#endif // MICROPY_SSL_MBEDTLS
STATIC MP_DEFINE_CONST_FUN_OBJ_2(uhashlib_md5_update_obj, uhashlib_md5_update);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(uhashlib_md5_digest_obj, uhashlib_md5_digest);
STATIC const mp_rom_map_elem_t uhashlib_md5_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&uhashlib_md5_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&uhashlib_md5_digest_obj) },
};
STATIC MP_DEFINE_CONST_DICT(uhashlib_md5_locals_dict, uhashlib_md5_locals_dict_table);
STATIC const mp_obj_type_t uhashlib_md5_type = {
{ &mp_type_type },
.name = MP_QSTR_md5,
.make_new = uhashlib_md5_make_new,
.locals_dict = (void *)&uhashlib_md5_locals_dict,
};
#endif // MICROPY_PY_UHASHLIB_MD5
STATIC const mp_rom_map_elem_t mp_module_uhashlib_globals_table[] = { STATIC const mp_rom_map_elem_t mp_module_uhashlib_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_hashlib) }, { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_hashlib) },
#if MICROPY_PY_UHASHLIB_SHA256 #if MICROPY_PY_UHASHLIB_SHA256
@ -219,17 +324,20 @@ STATIC const mp_rom_map_elem_t mp_module_uhashlib_globals_table[] = {
#if MICROPY_PY_UHASHLIB_SHA1 #if MICROPY_PY_UHASHLIB_SHA1
{ MP_ROM_QSTR(MP_QSTR_sha1), MP_ROM_PTR(&uhashlib_sha1_type) }, { MP_ROM_QSTR(MP_QSTR_sha1), MP_ROM_PTR(&uhashlib_sha1_type) },
#endif #endif
#if MICROPY_PY_UHASHLIB_MD5
{ MP_ROM_QSTR(MP_QSTR_md5), MP_ROM_PTR(&uhashlib_md5_type) },
#endif
}; };
STATIC MP_DEFINE_CONST_DICT(mp_module_uhashlib_globals, mp_module_uhashlib_globals_table); STATIC MP_DEFINE_CONST_DICT(mp_module_uhashlib_globals, mp_module_uhashlib_globals_table);
const mp_obj_module_t mp_module_uhashlib = { const mp_obj_module_t mp_module_uhashlib = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_uhashlib_globals, .globals = (mp_obj_dict_t *)&mp_module_uhashlib_globals,
}; };
#if MICROPY_PY_UHASHLIB_SHA256 #if MICROPY_PY_UHASHLIB_SHA256
#include "crypto-algorithms/sha256.c" #include "crypto-algorithms/sha256.c"
#endif #endif
#endif //MICROPY_PY_UHASHLIB #endif // MICROPY_PY_UHASHLIB

View file

@ -95,7 +95,7 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_uheapq_globals, mp_module_uheapq_globals_t
const mp_obj_module_t mp_module_uheapq = { const mp_obj_module_t mp_module_uheapq = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_uheapq_globals, .globals = (mp_obj_dict_t *)&mp_module_uheapq_globals,
}; };
#endif //MICROPY_PY_UHEAPQ #endif // MICROPY_PY_UHEAPQ

View file

@ -85,8 +85,8 @@ STATIC byte ujson_stream_next(ujson_stream_t *s) {
#define CIRCUITPY_JSON_READ_CHUNK_SIZE 64 #define CIRCUITPY_JSON_READ_CHUNK_SIZE 64
STATIC mp_uint_t ujson_python_readinto(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode) { STATIC mp_uint_t ujson_python_readinto(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode) {
(void) size; // Ignore size because we know it's always 1. (void)size; // Ignore size because we know it's always 1.
ujson_stream_t* s = obj; ujson_stream_t *s = obj;
if (s->start == s->end) { if (s->start == s->end) {
*errcode = 0; *errcode = 0;
@ -99,7 +99,7 @@ STATIC mp_uint_t ujson_python_readinto(mp_obj_t obj, void *buf, mp_uint_t size,
s->end = mp_obj_get_int(ret); s->end = mp_obj_get_int(ret);
} }
*((uint8_t *)buf) = ((uint8_t*) s->bytearray_obj.items)[s->start]; *((uint8_t *)buf) = ((uint8_t *)s->bytearray_obj.items)[s->start];
s->start++; s->start++;
return 1; return 1;
} }
@ -139,7 +139,7 @@ STATIC mp_obj_t _mod_ujson_load(mp_obj_t stream_obj, bool return_first_json) {
mp_obj_t stack_key = MP_OBJ_NULL; mp_obj_t stack_key = MP_OBJ_NULL;
S_NEXT(s); S_NEXT(s);
for (;;) { for (;;) {
cont: cont:
if (S_END(s)) { if (S_END(s)) {
break; break;
} }
@ -186,11 +186,21 @@ STATIC mp_obj_t _mod_ujson_load(mp_obj_t stream_obj, bool return_first_json) {
if (c == '\\') { if (c == '\\') {
c = S_NEXT(s); c = S_NEXT(s);
switch (c) { switch (c) {
case 'b': c = 0x08; break; case 'b':
case 'f': c = 0x0c; break; c = 0x08;
case 'n': c = 0x0a; break; break;
case 'r': c = 0x0d; break; case 'f':
case 't': c = 0x09; break; c = 0x0c;
break;
case 'n':
c = 0x0a;
break;
case 'r':
c = 0x0d;
break;
case 't':
c = 0x09;
break;
case 'u': { case 'u': {
mp_uint_t num = 0; mp_uint_t num = 0;
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
@ -216,7 +226,16 @@ STATIC mp_obj_t _mod_ujson_load(mp_obj_t stream_obj, bool return_first_json) {
next = mp_obj_new_str(vstr.buf, vstr.len); next = mp_obj_new_str(vstr.buf, vstr.len);
break; break;
case '-': case '-':
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': {
bool flt = false; bool flt = false;
vstr_reset(&vstr); vstr_reset(&vstr);
for (;;) { for (;;) {
@ -298,7 +317,7 @@ STATIC mp_obj_t _mod_ujson_load(mp_obj_t stream_obj, bool return_first_json) {
} }
} }
} }
success: success:
// It is legal for a stream to have contents after JSON. // It is legal for a stream to have contents after JSON.
// E.g., A UART is not closed after receiving an object; in load() we will // E.g., A UART is not closed after receiving an object; in load() we will
// return the first complete JSON object, while in loads() we will retain // return the first complete JSON object, while in loads() we will retain
@ -319,7 +338,7 @@ STATIC mp_obj_t _mod_ujson_load(mp_obj_t stream_obj, bool return_first_json) {
vstr_clear(&vstr); vstr_clear(&vstr);
return stack_top; return stack_top;
fail: fail:
mp_raise_ValueError(translate("syntax error in JSON")); mp_raise_ValueError(translate("syntax error in JSON"));
} }
@ -331,18 +350,18 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_load_obj, mod_ujson_load);
STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
size_t len; size_t len;
const char *buf = mp_obj_str_get_data(obj, &len); const char *buf = mp_obj_str_get_data(obj, &len);
vstr_t vstr = {len, len, (char*)buf, true}; vstr_t vstr = {len, len, (char *)buf, true};
mp_obj_stringio_t sio = {{&mp_type_stringio}, &vstr, 0, MP_OBJ_NULL}; mp_obj_stringio_t sio = {{&mp_type_stringio}, &vstr, 0, MP_OBJ_NULL};
return _mod_ujson_load(MP_OBJ_FROM_PTR(&sio), false); return _mod_ujson_load(MP_OBJ_FROM_PTR(&sio), false);
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_loads_obj, mod_ujson_loads); STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_loads_obj, mod_ujson_loads);
STATIC const mp_rom_map_elem_t mp_module_ujson_globals_table[] = { STATIC const mp_rom_map_elem_t mp_module_ujson_globals_table[] = {
#if CIRCUITPY #if CIRCUITPY
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_json) }, { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_json) },
#else #else
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ujson) }, { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ujson) },
#endif #endif
{ MP_ROM_QSTR(MP_QSTR_dump), MP_ROM_PTR(&mod_ujson_dump_obj) }, { MP_ROM_QSTR(MP_QSTR_dump), MP_ROM_PTR(&mod_ujson_dump_obj) },
{ MP_ROM_QSTR(MP_QSTR_dumps), MP_ROM_PTR(&mod_ujson_dumps_obj) }, { MP_ROM_QSTR(MP_QSTR_dumps), MP_ROM_PTR(&mod_ujson_dumps_obj) },
{ MP_ROM_QSTR(MP_QSTR_load), MP_ROM_PTR(&mod_ujson_load_obj) }, { MP_ROM_QSTR(MP_QSTR_load), MP_ROM_PTR(&mod_ujson_load_obj) },
@ -353,7 +372,7 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_ujson_globals, mp_module_ujson_globals_tab
const mp_obj_module_t mp_module_ujson = { const mp_obj_module_t mp_module_ujson = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_ujson_globals, .globals = (mp_obj_dict_t *)&mp_module_ujson_globals,
}; };
#endif //MICROPY_PY_UJSON #endif // MICROPY_PY_UJSON

View file

@ -18,15 +18,14 @@
STATIC uint32_t yasmarang_pad = 0xeda4baba, yasmarang_n = 69, yasmarang_d = 233; STATIC uint32_t yasmarang_pad = 0xeda4baba, yasmarang_n = 69, yasmarang_d = 233;
STATIC uint8_t yasmarang_dat = 0; STATIC uint8_t yasmarang_dat = 0;
STATIC uint32_t yasmarang(void) STATIC uint32_t yasmarang(void) {
{ yasmarang_pad += yasmarang_dat + yasmarang_d * yasmarang_n;
yasmarang_pad += yasmarang_dat + yasmarang_d * yasmarang_n; yasmarang_pad = (yasmarang_pad << 3) + (yasmarang_pad >> 29);
yasmarang_pad = (yasmarang_pad<<3) + (yasmarang_pad>>29); yasmarang_n = yasmarang_pad | 2;
yasmarang_n = yasmarang_pad | 2; yasmarang_d ^= (yasmarang_pad << 31) + (yasmarang_pad >> 1);
yasmarang_d ^= (yasmarang_pad<<31) + (yasmarang_pad>>1); yasmarang_dat ^= (char)yasmarang_pad ^ (yasmarang_d >> 8) ^ 1;
yasmarang_dat ^= (char) yasmarang_pad ^ (yasmarang_d>>8) ^ 1;
return (yasmarang_pad^(yasmarang_d<<5)^(yasmarang_pad>>18)^(yasmarang_dat<<1)); return yasmarang_pad ^ (yasmarang_d << 5) ^ (yasmarang_pad >> 18) ^ (yasmarang_dat << 1);
} /* yasmarang */ } /* yasmarang */
// End of Yasmarang // End of Yasmarang
@ -148,9 +147,11 @@ STATIC mp_float_t yasmarang_float(void) {
union { union {
mp_float_t f; mp_float_t f;
#if MP_ENDIANNESS_LITTLE #if MP_ENDIANNESS_LITTLE
struct { mp_float_int_t frc:MP_FLOAT_FRAC_BITS, exp:MP_FLOAT_EXP_BITS, sgn:1; } p; struct { mp_float_int_t frc : MP_FLOAT_FRAC_BITS, exp : MP_FLOAT_EXP_BITS, sgn : 1;
} p;
#else #else
struct { mp_float_int_t sgn:1, exp:MP_FLOAT_EXP_BITS, frc:MP_FLOAT_FRAC_BITS; } p; struct { mp_float_int_t sgn : 1, exp : MP_FLOAT_EXP_BITS, frc : MP_FLOAT_FRAC_BITS;
} p;
#endif #endif
} u; } u;
u.p.sgn = 0; u.p.sgn = 0;
@ -198,7 +199,7 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_urandom_globals, mp_module_urandom_globals
const mp_obj_module_t mp_module_urandom = { const mp_obj_module_t mp_module_urandom = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_urandom_globals, .globals = (mp_obj_dict_t *)&mp_module_urandom_globals,
}; };
#endif //MICROPY_PY_URANDOM #endif // MICROPY_PY_URANDOM

View file

@ -18,7 +18,9 @@
#include "re1.5/re1.5.h" #include "re1.5/re1.5.h"
#if CIRCUITPY_RE_DEBUG
#define FLAG_DEBUG 0x1000 #define FLAG_DEBUG 0x1000
#endif
typedef struct _mp_obj_re_t { typedef struct _mp_obj_re_t {
mp_obj_base_t base; mp_obj_base_t base;
@ -52,7 +54,7 @@ STATIC mp_obj_t match_group(mp_obj_t self_in, mp_obj_t no_in) {
return mp_const_none; return mp_const_none;
} }
return mp_obj_new_str_of_type(mp_obj_get_type(self->str), return mp_obj_new_str_of_type(mp_obj_get_type(self->str),
(const byte*)start, self->caps[no * 2 + 1] - start); (const byte *)start, self->caps[no * 2 + 1] - start);
} }
MP_DEFINE_CONST_FUN_OBJ_2(match_group_obj, match_group); MP_DEFINE_CONST_FUN_OBJ_2(match_group_obj, match_group);
@ -141,7 +143,7 @@ STATIC const mp_obj_type_t match_type = {
{ &mp_type_type }, { &mp_type_type },
.name = MP_QSTR_match, .name = MP_QSTR_match,
.print = match_print, .print = match_print,
.locals_dict = (void*)&match_locals_dict, .locals_dict = (void *)&match_locals_dict,
}; };
STATIC void re_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { STATIC void re_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
@ -157,7 +159,7 @@ STATIC mp_obj_t ure_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
size_t len; size_t len;
subj.begin = mp_obj_str_get_data(args[1], &len); subj.begin = mp_obj_str_get_data(args[1], &len);
subj.end = subj.begin + len; subj.end = subj.begin + len;
#if MICROPY_PY_URE_MATCH_SPAN_START_END #if MICROPY_PY_URE_MATCH_SPAN_START_END
if (n_args > 2) { if (n_args > 2) {
const mp_obj_type_t *self_type = mp_obj_get_type(args[1]); const mp_obj_type_t *self_type = mp_obj_get_type(args[1]);
mp_int_t str_len = MP_OBJ_SMALL_INT_VALUE(mp_obj_len_maybe(args[1])); mp_int_t str_len = MP_OBJ_SMALL_INT_VALUE(mp_obj_len_maybe(args[1]));
@ -185,14 +187,14 @@ STATIC mp_obj_t ure_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
subj.begin = (const char *)pos_ptr; subj.begin = (const char *)pos_ptr;
subj.end = (const char *)endpos_ptr; subj.end = (const char *)endpos_ptr;
} }
#endif #endif
int caps_num = (self->re.sub + 1) * 2; int caps_num = (self->re.sub + 1) * 2;
mp_obj_match_t *match = m_new_obj_var(mp_obj_match_t, char*, caps_num); mp_obj_match_t *match = m_new_obj_var(mp_obj_match_t, char *, caps_num);
// cast is a workaround for a bug in msvc: it treats const char** as a const pointer instead of a pointer to pointer to const char // cast is a workaround for a bug in msvc: it treats const char** as a const pointer instead of a pointer to pointer to const char
memset((char*)match->caps, 0, caps_num * sizeof(char*)); memset((char *)match->caps, 0, caps_num * sizeof(char *));
int res = re1_5_recursiveloopprog(&self->re, &subj, match->caps, caps_num, is_anchored); int res = re1_5_recursiveloopprog(&self->re, &subj, match->caps, caps_num, is_anchored);
if (res == 0) { if (res == 0) {
m_del_var(mp_obj_match_t, char*, caps_num, match); m_del_var(mp_obj_match_t, char *, caps_num, match);
return mp_const_none; return mp_const_none;
} }
@ -227,10 +229,10 @@ STATIC mp_obj_t re_split(size_t n_args, const mp_obj_t *args) {
} }
mp_obj_t retval = mp_obj_new_list(0, NULL); mp_obj_t retval = mp_obj_new_list(0, NULL);
const char **caps = mp_local_alloc(caps_num * sizeof(char*)); const char **caps = mp_local_alloc(caps_num * sizeof(char *));
while (true) { while (true) {
// cast is a workaround for a bug in msvc: it treats const char** as a const pointer instead of a pointer to pointer to const char // cast is a workaround for a bug in msvc: it treats const char** as a const pointer instead of a pointer to pointer to const char
memset((char**)caps, 0, caps_num * sizeof(char*)); memset((char **)caps, 0, caps_num * sizeof(char *));
int res = re1_5_recursiveloopprog(&self->re, &subj, caps, caps_num, false); int res = re1_5_recursiveloopprog(&self->re, &subj, caps, caps_num, false);
// if we didn't have a match, or had an empty match, it's time to stop // if we didn't have a match, or had an empty match, it's time to stop
@ -238,7 +240,7 @@ STATIC mp_obj_t re_split(size_t n_args, const mp_obj_t *args) {
break; break;
} }
mp_obj_t s = mp_obj_new_str_of_type(str_type, (const byte*)subj.begin, caps[0] - subj.begin); mp_obj_t s = mp_obj_new_str_of_type(str_type, (const byte *)subj.begin, caps[0] - subj.begin);
mp_obj_list_append(retval, s); mp_obj_list_append(retval, s);
if (self->re.sub > 0) { if (self->re.sub > 0) {
mp_raise_NotImplementedError(translate("Splitting with sub-captures")); mp_raise_NotImplementedError(translate("Splitting with sub-captures"));
@ -249,9 +251,9 @@ STATIC mp_obj_t re_split(size_t n_args, const mp_obj_t *args) {
} }
} }
// cast is a workaround for a bug in msvc (see above) // cast is a workaround for a bug in msvc (see above)
mp_local_free((char**)caps); mp_local_free((char **)caps);
mp_obj_t s = mp_obj_new_str_of_type(str_type, (const byte*)subj.begin, subj.end - subj.begin); mp_obj_t s = mp_obj_new_str_of_type(str_type, (const byte *)subj.begin, subj.end - subj.begin);
mp_obj_list_append(retval, s); mp_obj_list_append(retval, s);
return retval; return retval;
} }
@ -278,14 +280,14 @@ STATIC mp_obj_t re_sub_helper(mp_obj_t self_in, size_t n_args, const mp_obj_t *a
vstr_t vstr_return; vstr_t vstr_return;
vstr_return.buf = NULL; // We'll init the vstr after the first match vstr_return.buf = NULL; // We'll init the vstr after the first match
mp_obj_match_t *match = mp_local_alloc(sizeof(mp_obj_match_t) + caps_num * sizeof(char*)); mp_obj_match_t *match = mp_local_alloc(sizeof(mp_obj_match_t) + caps_num * sizeof(char *));
match->base.type = &match_type; match->base.type = &match_type;
match->num_matches = caps_num / 2; // caps_num counts start and end pointers match->num_matches = caps_num / 2; // caps_num counts start and end pointers
match->str = where; match->str = where;
for (;;) { for (;;) {
// cast is a workaround for a bug in msvc: it treats const char** as a const pointer instead of a pointer to pointer to const char // cast is a workaround for a bug in msvc: it treats const char** as a const pointer instead of a pointer to pointer to const char
memset((char*)match->caps, 0, caps_num * sizeof(char*)); memset((char *)match->caps, 0, caps_num * sizeof(char *));
int res = re1_5_recursiveloopprog(&self->re, &subj, match->caps, caps_num, false); int res = re1_5_recursiveloopprog(&self->re, &subj, match->caps, caps_num, false);
// If we didn't have a match, or had an empty match, it's time to stop // If we didn't have a match, or had an empty match, it's time to stop
@ -302,7 +304,7 @@ STATIC mp_obj_t re_sub_helper(mp_obj_t self_in, size_t n_args, const mp_obj_t *a
vstr_add_strn(&vstr_return, subj.begin, match->caps[0] - subj.begin); vstr_add_strn(&vstr_return, subj.begin, match->caps[0] - subj.begin);
// Get replacement string // Get replacement string
const char* repl = mp_obj_str_get_str((mp_obj_is_callable(replace) ? mp_call_function_1(replace, MP_OBJ_FROM_PTR(match)) : replace)); const char *repl = mp_obj_str_get_str((mp_obj_is_callable(replace) ? mp_call_function_1(replace, MP_OBJ_FROM_PTR(match)) : replace));
// Append replacement string to result, substituting any regex groups // Append replacement string to result, substituting any regex groups
while (*repl != '\0') { while (*repl != '\0') {
@ -384,13 +386,13 @@ STATIC MP_DEFINE_CONST_DICT(re_locals_dict, re_locals_dict_table);
STATIC const mp_obj_type_t re_type = { STATIC const mp_obj_type_t re_type = {
{ &mp_type_type }, { &mp_type_type },
#if CIRCUITPY #if CIRCUITPY
.name = MP_QSTR_re, .name = MP_QSTR_re,
#else #else
.name = MP_QSTR_ure, .name = MP_QSTR_ure,
#endif #endif
.print = re_print, .print = re_print,
.locals_dict = (void*)&re_locals_dict, .locals_dict = (void *)&re_locals_dict,
}; };
STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) {
@ -401,18 +403,24 @@ STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) {
} }
mp_obj_re_t *o = m_new_obj_var(mp_obj_re_t, char, size); mp_obj_re_t *o = m_new_obj_var(mp_obj_re_t, char, size);
o->base.type = &re_type; o->base.type = &re_type;
#if CIRCUITPY_RE_DEBUG
int flags = 0; int flags = 0;
if (n_args > 1) { if (n_args > 1) {
flags = mp_obj_get_int(args[1]); flags = mp_obj_get_int(args[1]);
} }
#else
(void)n_args;
#endif
int error = re1_5_compilecode(&o->re, re_str); int error = re1_5_compilecode(&o->re, re_str);
if (error != 0) { if (error != 0) {
error: error:
mp_raise_ValueError(translate("Error in regex")); mp_raise_ValueError(translate("Error in regex"));
} }
#if CIRCUITPY_RE_DEBUG
if (flags & FLAG_DEBUG) { if (flags & FLAG_DEBUG) {
re1_5_dumpcode(&o->re); re1_5_dumpcode(&o->re);
} }
#endif
return MP_OBJ_FROM_PTR(o); return MP_OBJ_FROM_PTR(o);
} }
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_compile_obj, 1, 2, mod_re_compile); MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_compile_obj, 1, 2, mod_re_compile);
@ -445,25 +453,27 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_sub_obj, 3, 5, mod_re_sub);
#endif #endif
STATIC const mp_rom_map_elem_t mp_module_re_globals_table[] = { STATIC const mp_rom_map_elem_t mp_module_re_globals_table[] = {
#if CIRCUITPY #if CIRCUITPY
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_re) }, { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_re) },
#else #else
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ure) }, { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ure) },
#endif #endif
{ MP_ROM_QSTR(MP_QSTR_compile), MP_ROM_PTR(&mod_re_compile_obj) }, { MP_ROM_QSTR(MP_QSTR_compile), MP_ROM_PTR(&mod_re_compile_obj) },
{ MP_ROM_QSTR(MP_QSTR_match), MP_ROM_PTR(&mod_re_match_obj) }, { MP_ROM_QSTR(MP_QSTR_match), MP_ROM_PTR(&mod_re_match_obj) },
{ MP_ROM_QSTR(MP_QSTR_search), MP_ROM_PTR(&mod_re_search_obj) }, { MP_ROM_QSTR(MP_QSTR_search), MP_ROM_PTR(&mod_re_search_obj) },
#if MICROPY_PY_URE_SUB #if MICROPY_PY_URE_SUB
{ MP_ROM_QSTR(MP_QSTR_sub), MP_ROM_PTR(&mod_re_sub_obj) }, { MP_ROM_QSTR(MP_QSTR_sub), MP_ROM_PTR(&mod_re_sub_obj) },
#endif #endif
#if CIRCUITPY_RE_DEBUG
{ MP_ROM_QSTR(MP_QSTR_DEBUG), MP_ROM_INT(FLAG_DEBUG) }, { MP_ROM_QSTR(MP_QSTR_DEBUG), MP_ROM_INT(FLAG_DEBUG) },
#endif
}; };
STATIC MP_DEFINE_CONST_DICT(mp_module_re_globals, mp_module_re_globals_table); STATIC MP_DEFINE_CONST_DICT(mp_module_re_globals, mp_module_re_globals_table);
const mp_obj_module_t mp_module_ure = { const mp_obj_module_t mp_module_ure = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_re_globals, .globals = (mp_obj_dict_t *)&mp_module_re_globals,
}; };
// Source files #include'd here to make sure they're compiled in // Source files #include'd here to make sure they're compiled in
@ -471,8 +481,10 @@ const mp_obj_module_t mp_module_ure = {
#define re1_5_fatal(x) assert(!x) #define re1_5_fatal(x) assert(!x)
#include "re1.5/compilecode.c" #include "re1.5/compilecode.c"
#if CIRCUITPY_RE_DEBUG
#include "re1.5/dumpcode.c" #include "re1.5/dumpcode.c"
#endif
#include "re1.5/recursiveloop.c" #include "re1.5/recursiveloop.c"
#include "re1.5/charclass.c" #include "re1.5/charclass.c"
#endif //MICROPY_PY_URE #endif // MICROPY_PY_URE

View file

@ -25,7 +25,7 @@
typedef struct _poll_obj_t { typedef struct _poll_obj_t {
mp_obj_t obj; mp_obj_t obj;
mp_uint_t (*ioctl)(mp_obj_t obj, mp_uint_t request, mp_uint_t arg, int *errcode); mp_uint_t (*ioctl)(mp_obj_t obj, mp_uint_t request, uintptr_t arg, int *errcode);
mp_uint_t flags; mp_uint_t flags;
mp_uint_t flags_ret; mp_uint_t flags_ret;
} poll_obj_t; } poll_obj_t;
@ -33,7 +33,7 @@ typedef struct _poll_obj_t {
STATIC void poll_map_add(mp_map_t *poll_map, const mp_obj_t *obj, mp_uint_t obj_len, mp_uint_t flags, bool or_flags) { STATIC void poll_map_add(mp_map_t *poll_map, const mp_obj_t *obj, mp_uint_t obj_len, mp_uint_t flags, bool or_flags) {
for (mp_uint_t i = 0; i < obj_len; i++) { for (mp_uint_t i = 0; i < obj_len; i++) {
mp_map_elem_t *elem = mp_map_lookup(poll_map, mp_obj_id(obj[i]), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND); mp_map_elem_t *elem = mp_map_lookup(poll_map, mp_obj_id(obj[i]), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND);
if (elem->value == NULL) { if (elem->value == MP_OBJ_NULL) {
// object not found; get its ioctl and add it to the poll list // object not found; get its ioctl and add it to the poll list
const mp_stream_p_t *stream_p = mp_get_stream_raise(obj[i], MP_STREAM_OP_IOCTL); const mp_stream_p_t *stream_p = mp_get_stream_raise(obj[i], MP_STREAM_OP_IOCTL);
poll_obj_t *poll_obj = m_new_obj(poll_obj_t); poll_obj_t *poll_obj = m_new_obj(poll_obj_t);
@ -41,27 +41,27 @@ STATIC void poll_map_add(mp_map_t *poll_map, const mp_obj_t *obj, mp_uint_t obj_
poll_obj->ioctl = stream_p->ioctl; poll_obj->ioctl = stream_p->ioctl;
poll_obj->flags = flags; poll_obj->flags = flags;
poll_obj->flags_ret = 0; poll_obj->flags_ret = 0;
elem->value = poll_obj; elem->value = MP_OBJ_FROM_PTR(poll_obj);
} else { } else {
// object exists; update its flags // object exists; update its flags
if (or_flags) { if (or_flags) {
((poll_obj_t*)elem->value)->flags |= flags; ((poll_obj_t *)MP_OBJ_TO_PTR(elem->value))->flags |= flags;
} else { } else {
((poll_obj_t*)elem->value)->flags = flags; ((poll_obj_t *)MP_OBJ_TO_PTR(elem->value))->flags = flags;
} }
} }
} }
} }
// poll each object in the map // poll each object in the map
STATIC mp_uint_t poll_map_poll(mp_map_t *poll_map, mp_uint_t *rwx_num) { STATIC mp_uint_t poll_map_poll(mp_map_t *poll_map, size_t *rwx_num) {
mp_uint_t n_ready = 0; mp_uint_t n_ready = 0;
for (mp_uint_t i = 0; i < poll_map->alloc; ++i) { for (mp_uint_t i = 0; i < poll_map->alloc; ++i) {
if (!MP_MAP_SLOT_IS_FILLED(poll_map, i)) { if (!MP_MAP_SLOT_IS_FILLED(poll_map, i)) {
continue; continue;
} }
poll_obj_t *poll_obj = (poll_obj_t*)poll_map->table[i].value; poll_obj_t *poll_obj = MP_OBJ_TO_PTR(poll_map->table[i].value);
int errcode; int errcode;
mp_int_t ret = poll_obj->ioctl(poll_obj->obj, MP_STREAM_POLL, poll_obj->flags, &errcode); mp_int_t ret = poll_obj->ioctl(poll_obj->obj, MP_STREAM_POLL, poll_obj->flags, &errcode);
poll_obj->flags_ret = ret; poll_obj->flags_ret = ret;
@ -138,15 +138,15 @@ STATIC mp_obj_t select_select(uint n_args, const mp_obj_t *args) {
if (!MP_MAP_SLOT_IS_FILLED(&poll_map, i)) { if (!MP_MAP_SLOT_IS_FILLED(&poll_map, i)) {
continue; continue;
} }
poll_obj_t *poll_obj = (poll_obj_t*)poll_map.table[i].value; poll_obj_t *poll_obj = MP_OBJ_TO_PTR(poll_map.table[i].value);
if (poll_obj->flags_ret & MP_STREAM_POLL_RD) { if (poll_obj->flags_ret & MP_STREAM_POLL_RD) {
((mp_obj_list_t*)list_array[0])->items[rwx_len[0]++] = poll_obj->obj; ((mp_obj_list_t *)MP_OBJ_TO_PTR(list_array[0]))->items[rwx_len[0]++] = poll_obj->obj;
} }
if (poll_obj->flags_ret & MP_STREAM_POLL_WR) { if (poll_obj->flags_ret & MP_STREAM_POLL_WR) {
((mp_obj_list_t*)list_array[1])->items[rwx_len[1]++] = poll_obj->obj; ((mp_obj_list_t *)MP_OBJ_TO_PTR(list_array[1]))->items[rwx_len[1]++] = poll_obj->obj;
} }
if ((poll_obj->flags_ret & ~(MP_STREAM_POLL_RD | MP_STREAM_POLL_WR)) != 0) { if ((poll_obj->flags_ret & ~(MP_STREAM_POLL_RD | MP_STREAM_POLL_WR)) != 0) {
((mp_obj_list_t*)list_array[2])->items[rwx_len[2]++] = poll_obj->obj; ((mp_obj_list_t *)MP_OBJ_TO_PTR(list_array[2]))->items[rwx_len[2]++] = poll_obj->obj;
} }
} }
mp_map_deinit(&poll_map); mp_map_deinit(&poll_map);
@ -171,7 +171,7 @@ typedef struct _mp_obj_poll_t {
/// \method register(obj[, eventmask]) /// \method register(obj[, eventmask])
STATIC mp_obj_t poll_register(uint n_args, const mp_obj_t *args) { STATIC mp_obj_t poll_register(uint n_args, const mp_obj_t *args) {
mp_obj_poll_t *self = args[0]; mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]);
mp_uint_t flags; mp_uint_t flags;
if (n_args == 3) { if (n_args == 3) {
flags = mp_obj_get_int(args[2]); flags = mp_obj_get_int(args[2]);
@ -185,7 +185,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poll_register_obj, 2, 3, poll_register);
/// \method unregister(obj) /// \method unregister(obj)
STATIC mp_obj_t poll_unregister(mp_obj_t self_in, mp_obj_t obj_in) { STATIC mp_obj_t poll_unregister(mp_obj_t self_in, mp_obj_t obj_in) {
mp_obj_poll_t *self = self_in; mp_obj_poll_t *self = MP_OBJ_TO_PTR(self_in);
mp_map_lookup(&self->poll_map, mp_obj_id(obj_in), MP_MAP_LOOKUP_REMOVE_IF_FOUND); mp_map_lookup(&self->poll_map, mp_obj_id(obj_in), MP_MAP_LOOKUP_REMOVE_IF_FOUND);
// TODO raise KeyError if obj didn't exist in map // TODO raise KeyError if obj didn't exist in map
return mp_const_none; return mp_const_none;
@ -194,18 +194,18 @@ MP_DEFINE_CONST_FUN_OBJ_2(poll_unregister_obj, poll_unregister);
/// \method modify(obj, eventmask) /// \method modify(obj, eventmask)
STATIC mp_obj_t poll_modify(mp_obj_t self_in, mp_obj_t obj_in, mp_obj_t eventmask_in) { STATIC mp_obj_t poll_modify(mp_obj_t self_in, mp_obj_t obj_in, mp_obj_t eventmask_in) {
mp_obj_poll_t *self = self_in; mp_obj_poll_t *self = MP_OBJ_TO_PTR(self_in);
mp_map_elem_t *elem = mp_map_lookup(&self->poll_map, mp_obj_id(obj_in), MP_MAP_LOOKUP); mp_map_elem_t *elem = mp_map_lookup(&self->poll_map, mp_obj_id(obj_in), MP_MAP_LOOKUP);
if (elem == NULL) { if (elem == NULL) {
mp_raise_OSError(MP_ENOENT); mp_raise_OSError(MP_ENOENT);
} }
((poll_obj_t*)elem->value)->flags = mp_obj_get_int(eventmask_in); ((poll_obj_t *)MP_OBJ_TO_PTR(elem->value))->flags = mp_obj_get_int(eventmask_in);
return mp_const_none; return mp_const_none;
} }
MP_DEFINE_CONST_FUN_OBJ_3(poll_modify_obj, poll_modify); MP_DEFINE_CONST_FUN_OBJ_3(poll_modify_obj, poll_modify);
STATIC mp_uint_t poll_poll_internal(uint n_args, const mp_obj_t *args) { STATIC mp_uint_t poll_poll_internal(uint n_args, const mp_obj_t *args) {
mp_obj_poll_t *self = args[0]; mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]);
// work out timeout (its given already in ms) // work out timeout (its given already in ms)
mp_uint_t timeout = -1; mp_uint_t timeout = -1;
@ -238,18 +238,18 @@ STATIC mp_uint_t poll_poll_internal(uint n_args, const mp_obj_t *args) {
return n_ready; return n_ready;
} }
STATIC mp_obj_t poll_poll(uint n_args, const mp_obj_t *args) { STATIC mp_obj_t poll_poll(size_t n_args, const mp_obj_t *args) {
mp_obj_poll_t *self = args[0]; mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]);
mp_uint_t n_ready = poll_poll_internal(n_args, args); mp_uint_t n_ready = poll_poll_internal(n_args, args);
// one or more objects are ready, or we had a timeout // one or more objects are ready, or we had a timeout
mp_obj_list_t *ret_list = mp_obj_new_list(n_ready, NULL); mp_obj_list_t *ret_list = MP_OBJ_TO_PTR(mp_obj_new_list(n_ready, NULL));
n_ready = 0; n_ready = 0;
for (mp_uint_t i = 0; i < self->poll_map.alloc; ++i) { for (mp_uint_t i = 0; i < self->poll_map.alloc; ++i) {
if (!MP_MAP_SLOT_IS_FILLED(&self->poll_map, i)) { if (!MP_MAP_SLOT_IS_FILLED(&self->poll_map, i)) {
continue; continue;
} }
poll_obj_t *poll_obj = (poll_obj_t*)self->poll_map.table[i].value; poll_obj_t *poll_obj = MP_OBJ_TO_PTR(self->poll_map.table[i].value);
if (poll_obj->flags_ret != 0) { if (poll_obj->flags_ret != 0) {
mp_obj_t tuple[2] = {poll_obj->obj, MP_OBJ_NEW_SMALL_INT(poll_obj->flags_ret)}; mp_obj_t tuple[2] = {poll_obj->obj, MP_OBJ_NEW_SMALL_INT(poll_obj->flags_ret)};
ret_list->items[n_ready++] = mp_obj_new_tuple(2, tuple); ret_list->items[n_ready++] = mp_obj_new_tuple(2, tuple);
@ -259,7 +259,7 @@ STATIC mp_obj_t poll_poll(uint n_args, const mp_obj_t *args) {
} }
} }
} }
return ret_list; return MP_OBJ_FROM_PTR(ret_list);
} }
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poll_poll_obj, 1, 3, poll_poll); MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poll_poll_obj, 1, 3, poll_poll);
@ -292,7 +292,7 @@ STATIC mp_obj_t poll_iternext(mp_obj_t self_in) {
if (!MP_MAP_SLOT_IS_FILLED(&self->poll_map, i)) { if (!MP_MAP_SLOT_IS_FILLED(&self->poll_map, i)) {
continue; continue;
} }
poll_obj_t *poll_obj = (poll_obj_t*)self->poll_map.table[i].value; poll_obj_t *poll_obj = MP_OBJ_TO_PTR(self->poll_map.table[i].value);
if (poll_obj->flags_ret != 0) { if (poll_obj->flags_ret != 0) {
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(self->ret_tuple); mp_obj_tuple_t *t = MP_OBJ_TO_PTR(self->ret_tuple);
t->items[0] = poll_obj->obj; t->items[0] = poll_obj->obj;
@ -324,7 +324,7 @@ STATIC const mp_obj_type_t mp_type_poll = {
.name = MP_QSTR_poll, .name = MP_QSTR_poll,
.getiter = mp_identity_getiter, .getiter = mp_identity_getiter,
.iternext = poll_iternext, .iternext = poll_iternext,
.locals_dict = (void*)&poll_locals_dict, .locals_dict = (void *)&poll_locals_dict,
}; };
/// \function poll() /// \function poll()
@ -334,7 +334,7 @@ STATIC mp_obj_t select_poll(void) {
mp_map_init(&poll->poll_map, 0); mp_map_init(&poll->poll_map, 0);
poll->iter_cnt = 0; poll->iter_cnt = 0;
poll->ret_tuple = MP_OBJ_NULL; poll->ret_tuple = MP_OBJ_NULL;
return poll; return MP_OBJ_FROM_PTR(poll);
} }
MP_DEFINE_CONST_FUN_OBJ_0(mp_select_poll_obj, select_poll); MP_DEFINE_CONST_FUN_OBJ_0(mp_select_poll_obj, select_poll);
@ -352,7 +352,7 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_select_globals, mp_module_select_globals_t
const mp_obj_module_t mp_module_uselect = { const mp_obj_module_t mp_module_uselect = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_select_globals, .globals = (mp_obj_dict_t *)&mp_module_select_globals,
}; };
#endif // MICROPY_PY_USELECT #endif // MICROPY_PY_USELECT

View file

@ -34,11 +34,11 @@ struct ssl_args {
STATIC const mp_obj_type_t ussl_socket_type; STATIC const mp_obj_type_t ussl_socket_type;
STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) { STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) {
#if MICROPY_PY_USSL_FINALISER #if MICROPY_PY_USSL_FINALISER
mp_obj_ssl_socket_t *o = m_new_obj_with_finaliser(mp_obj_ssl_socket_t); mp_obj_ssl_socket_t *o = m_new_obj_with_finaliser(mp_obj_ssl_socket_t);
#else #else
mp_obj_ssl_socket_t *o = m_new_obj(mp_obj_ssl_socket_t); mp_obj_ssl_socket_t *o = m_new_obj(mp_obj_ssl_socket_t);
#endif #endif
o->base.type = &ussl_socket_type; o->base.type = &ussl_socket_type;
o->buf = NULL; o->buf = NULL;
o->bytes_left = 0; o->bytes_left = 0;
@ -54,13 +54,13 @@ STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) {
if (args->key.u_obj != mp_const_none) { if (args->key.u_obj != mp_const_none) {
size_t len; size_t len;
const byte *data = (const byte*)mp_obj_str_get_data(args->key.u_obj, &len); const byte *data = (const byte *)mp_obj_str_get_data(args->key.u_obj, &len);
int res = ssl_obj_memory_load(o->ssl_ctx, SSL_OBJ_RSA_KEY, data, len, NULL); int res = ssl_obj_memory_load(o->ssl_ctx, SSL_OBJ_RSA_KEY, data, len, NULL);
if (res != SSL_OK) { if (res != SSL_OK) {
mp_raise_ValueError(translate("invalid key")); mp_raise_ValueError(translate("invalid key"));
} }
data = (const byte*)mp_obj_str_get_data(args->cert.u_obj, &len); data = (const byte *)mp_obj_str_get_data(args->cert.u_obj, &len);
res = ssl_obj_memory_load(o->ssl_ctx, SSL_OBJ_X509_CERT, data, len, NULL); res = ssl_obj_memory_load(o->ssl_ctx, SSL_OBJ_X509_CERT, data, len, NULL);
if (res != SSL_OK) { if (res != SSL_OK) {
mp_raise_ValueError(translate("invalid cert")); mp_raise_ValueError(translate("invalid cert"));
@ -73,7 +73,7 @@ STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) {
SSL_EXTENSIONS *ext = ssl_ext_new(); SSL_EXTENSIONS *ext = ssl_ext_new();
if (args->server_hostname.u_obj != mp_const_none) { if (args->server_hostname.u_obj != mp_const_none) {
ext->host_name = (char*)mp_obj_str_get_str(args->server_hostname.u_obj); ext->host_name = (char *)mp_obj_str_get_str(args->server_hostname.u_obj);
} }
o->ssl_sock = ssl_client_new(o->ssl_ctx, (long)sock, NULL, 0, ext); o->ssl_sock = ssl_client_new(o->ssl_ctx, (long)sock, NULL, 0, ext);
@ -158,21 +158,13 @@ STATIC mp_uint_t socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, in
STATIC mp_uint_t socket_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, int *errcode) { STATIC mp_uint_t socket_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, int *errcode) {
mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(o_in); mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(o_in);
(void)arg; if (request == MP_STREAM_CLOSE && self->ssl_sock != NULL) {
switch (request) { ssl_free(self->ssl_sock);
case MP_STREAM_CLOSE: ssl_ctx_free(self->ssl_ctx);
if (self->ssl_sock != NULL) { self->ssl_sock = NULL;
ssl_free(self->ssl_sock);
ssl_ctx_free(self->ssl_ctx);
self->ssl_sock = NULL;
mp_stream_close(self->sock);
}
return 0;
default:
*errcode = MP_EINVAL;
return MP_STREAM_ERROR;
} }
// Pass all requests down to the underlying socket
return mp_get_stream(self->sock)->ioctl(self->sock, request, arg, errcode);
} }
STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t flag_in) { STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t flag_in) {
@ -192,9 +184,9 @@ STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
{ MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) }, { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) },
{ MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) }, { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) },
#if MICROPY_PY_USSL_FINALISER #if MICROPY_PY_USSL_FINALISER
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) }, { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) },
#endif #endif
}; };
STATIC MP_DEFINE_CONST_DICT(ussl_socket_locals_dict, ussl_socket_locals_dict_table); STATIC MP_DEFINE_CONST_DICT(ussl_socket_locals_dict, ussl_socket_locals_dict_table);
@ -214,16 +206,16 @@ STATIC const mp_obj_type_t ussl_socket_type = {
.getiter = NULL, .getiter = NULL,
.iternext = NULL, .iternext = NULL,
.protocol = &ussl_socket_stream_p, .protocol = &ussl_socket_stream_p,
.locals_dict = (void*)&ussl_socket_locals_dict, .locals_dict = (void *)&ussl_socket_locals_dict,
}; };
STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
// TODO: Implement more args // TODO: Implement more args
static const mp_arg_t allowed_args[] = { static const mp_arg_t allowed_args[] = {
{ MP_QSTR_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} },
{ MP_QSTR_cert, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_cert, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} },
{ MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, { MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
{ MP_QSTR_server_hostname, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_server_hostname, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} },
}; };
// TODO: Check that sock implements stream protocol // TODO: Check that sock implements stream protocol
@ -231,7 +223,7 @@ STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_
struct ssl_args args; struct ssl_args args;
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args,
MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t*)&args); MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&args);
return MP_OBJ_FROM_PTR(socket_new(sock, &args)); return MP_OBJ_FROM_PTR(socket_new(sock, &args));
} }
@ -246,7 +238,7 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_ssl_globals, mp_module_ssl_globals_table);
const mp_obj_module_t mp_module_ussl = { const mp_obj_module_t mp_module_ussl = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_ssl_globals, .globals = (mp_obj_dict_t *)&mp_module_ssl_globals,
}; };
#endif // MICROPY_PY_USSL #endif // MICROPY_PY_USSL

View file

@ -53,7 +53,7 @@ STATIC void mbedtls_debug(void *ctx, int level, const char *file, int line, cons
#endif #endif
STATIC int _mbedtls_ssl_send(void *ctx, const byte *buf, size_t len) { STATIC int _mbedtls_ssl_send(void *ctx, const byte *buf, size_t len) {
mp_obj_t sock = *(mp_obj_t*)ctx; mp_obj_t sock = *(mp_obj_t *)ctx;
const mp_stream_p_t *sock_stream = mp_get_stream(sock); const mp_stream_p_t *sock_stream = mp_get_stream(sock);
int err; int err;
@ -70,7 +70,7 @@ STATIC int _mbedtls_ssl_send(void *ctx, const byte *buf, size_t len) {
} }
STATIC int _mbedtls_ssl_recv(void *ctx, byte *buf, size_t len) { STATIC int _mbedtls_ssl_recv(void *ctx, byte *buf, size_t len) {
mp_obj_t sock = *(mp_obj_t*)ctx; mp_obj_t sock = *(mp_obj_t *)ctx;
const mp_stream_p_t *sock_stream = mp_get_stream(sock); const mp_stream_p_t *sock_stream = mp_get_stream(sock);
int err; int err;
@ -91,11 +91,11 @@ STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) {
// Verify the socket object has the full stream protocol // Verify the socket object has the full stream protocol
mp_get_stream_raise(sock, MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL); mp_get_stream_raise(sock, MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL);
#if MICROPY_PY_USSL_FINALISER #if MICROPY_PY_USSL_FINALISER
mp_obj_ssl_socket_t *o = m_new_obj_with_finaliser(mp_obj_ssl_socket_t); mp_obj_ssl_socket_t *o = m_new_obj_with_finaliser(mp_obj_ssl_socket_t);
#else #else
mp_obj_ssl_socket_t *o = m_new_obj(mp_obj_ssl_socket_t); mp_obj_ssl_socket_t *o = m_new_obj(mp_obj_ssl_socket_t);
#endif #endif
o->base.type = &ussl_socket_type; o->base.type = &ussl_socket_type;
o->sock = sock; o->sock = sock;
@ -119,9 +119,9 @@ STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) {
} }
ret = mbedtls_ssl_config_defaults(&o->conf, ret = mbedtls_ssl_config_defaults(&o->conf,
args->server_side.u_bool ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT, args->server_side.u_bool ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT); MBEDTLS_SSL_PRESET_DEFAULT);
if (ret != 0) { if (ret != 0) {
goto cleanup; goto cleanup;
} }
@ -149,13 +149,13 @@ STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) {
if (args->key.u_obj != MP_OBJ_NULL) { if (args->key.u_obj != MP_OBJ_NULL) {
size_t key_len; size_t key_len;
const byte *key = (const byte*)mp_obj_str_get_data(args->key.u_obj, &key_len); const byte *key = (const byte *)mp_obj_str_get_data(args->key.u_obj, &key_len);
// len should include terminating null // len should include terminating null
ret = mbedtls_pk_parse_key(&o->pkey, key, key_len + 1, NULL, 0); ret = mbedtls_pk_parse_key(&o->pkey, key, key_len + 1, NULL, 0);
assert(ret == 0); assert(ret == 0);
size_t cert_len; size_t cert_len;
const byte *cert = (const byte*)mp_obj_str_get_data(args->cert.u_obj, &cert_len); const byte *cert = (const byte *)mp_obj_str_get_data(args->cert.u_obj, &cert_len);
// len should include terminating null // len should include terminating null
ret = mbedtls_x509_crt_parse(&o->cert, cert, cert_len + 1); ret = mbedtls_x509_crt_parse(&o->cert, cert, cert_len + 1);
assert(ret == 0); assert(ret == 0);
@ -194,7 +194,7 @@ STATIC mp_obj_t mod_ssl_getpeercert(mp_obj_t o_in, mp_obj_t binary_form) {
if (!mp_obj_is_true(binary_form)) { if (!mp_obj_is_true(binary_form)) {
mp_raise_NotImplementedError(NULL); mp_raise_NotImplementedError(NULL);
} }
const mbedtls_x509_crt* peer_cert = mbedtls_ssl_get_peer_cert(&o->ssl); const mbedtls_x509_crt *peer_cert = mbedtls_ssl_get_peer_cert(&o->ssl);
return mp_obj_new_bytes(peer_cert->raw.p, peer_cert->raw.len); return mp_obj_new_bytes(peer_cert->raw.p, peer_cert->raw.len);
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_ssl_getpeercert_obj, mod_ssl_getpeercert); STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_ssl_getpeercert_obj, mod_ssl_getpeercert);
@ -249,23 +249,17 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_setblocking_obj, socket_setblocking);
STATIC mp_uint_t socket_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, int *errcode) { STATIC mp_uint_t socket_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, int *errcode) {
mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(o_in); mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(o_in);
(void)arg; if (request == MP_STREAM_CLOSE) {
switch (request) { mbedtls_pk_free(&self->pkey);
case MP_STREAM_CLOSE: mbedtls_x509_crt_free(&self->cert);
mbedtls_pk_free(&self->pkey); mbedtls_x509_crt_free(&self->cacert);
mbedtls_x509_crt_free(&self->cert); mbedtls_ssl_free(&self->ssl);
mbedtls_x509_crt_free(&self->cacert); mbedtls_ssl_config_free(&self->conf);
mbedtls_ssl_free(&self->ssl); mbedtls_ctr_drbg_free(&self->ctr_drbg);
mbedtls_ssl_config_free(&self->conf); mbedtls_entropy_free(&self->entropy);
mbedtls_ctr_drbg_free(&self->ctr_drbg);
mbedtls_entropy_free(&self->entropy);
mp_stream_close(self->sock);
return 0;
default:
*errcode = MP_EINVAL;
return MP_STREAM_ERROR;
} }
// Pass all requests down to the underlying socket
return mp_get_stream(self->sock)->ioctl(self->sock, request, arg, errcode);
} }
STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = { STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = {
@ -275,9 +269,9 @@ STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
{ MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) }, { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) },
{ MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) }, { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) },
#if MICROPY_PY_USSL_FINALISER #if MICROPY_PY_USSL_FINALISER
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) }, { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) },
#endif #endif
{ MP_ROM_QSTR(MP_QSTR_getpeercert), MP_ROM_PTR(&mod_ssl_getpeercert_obj) }, { MP_ROM_QSTR(MP_QSTR_getpeercert), MP_ROM_PTR(&mod_ssl_getpeercert_obj) },
}; };
@ -298,7 +292,7 @@ STATIC const mp_obj_type_t ussl_socket_type = {
.getiter = NULL, .getiter = NULL,
.iternext = NULL, .iternext = NULL,
.protocol = &ussl_socket_stream_p, .protocol = &ussl_socket_stream_p,
.locals_dict = (void*)&ussl_socket_locals_dict, .locals_dict = (void *)&ussl_socket_locals_dict,
}; };
STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
@ -315,7 +309,7 @@ STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_
struct ssl_args args; struct ssl_args args;
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args,
MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t*)&args); MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&args);
return MP_OBJ_FROM_PTR(socket_new(sock, &args)); return MP_OBJ_FROM_PTR(socket_new(sock, &args));
} }
@ -330,7 +324,7 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_ssl_globals, mp_module_ssl_globals_table);
const mp_obj_module_t mp_module_ussl = { const mp_obj_module_t mp_module_ussl = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_ssl_globals, .globals = (mp_obj_dict_t *)&mp_module_ssl_globals,
}; };
#endif // MICROPY_PY_USSL #endif // MICROPY_PY_USSL

View file

@ -171,9 +171,12 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_utimeq_dump_obj, mod_utimeq_dump);
STATIC mp_obj_t utimeq_unary_op(mp_unary_op_t op, mp_obj_t self_in) { STATIC mp_obj_t utimeq_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
mp_obj_utimeq_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_utimeq_t *self = MP_OBJ_TO_PTR(self_in);
switch (op) { switch (op) {
case MP_UNARY_OP_BOOL: return mp_obj_new_bool(self->len != 0); case MP_UNARY_OP_BOOL:
case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(self->len); return mp_obj_new_bool(self->len != 0);
default: return MP_OBJ_NULL; // op not supported case MP_UNARY_OP_LEN:
return MP_OBJ_NEW_SMALL_INT(self->len);
default:
return MP_OBJ_NULL; // op not supported
} }
} }
@ -193,7 +196,7 @@ STATIC const mp_obj_type_t utimeq_type = {
.name = MP_QSTR_utimeq, .name = MP_QSTR_utimeq,
.make_new = utimeq_make_new, .make_new = utimeq_make_new,
.unary_op = utimeq_unary_op, .unary_op = utimeq_unary_op,
.locals_dict = (void*)&utimeq_locals_dict, .locals_dict = (void *)&utimeq_locals_dict,
}; };
STATIC const mp_rom_map_elem_t mp_module_utimeq_globals_table[] = { STATIC const mp_rom_map_elem_t mp_module_utimeq_globals_table[] = {
@ -205,7 +208,7 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_utimeq_globals, mp_module_utimeq_globals_t
const mp_obj_module_t mp_module_utimeq = { const mp_obj_module_t mp_module_utimeq = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_utimeq_globals, .globals = (mp_obj_dict_t *)&mp_module_utimeq_globals,
}; };
#endif //MICROPY_PY_UTIMEQ #endif // MICROPY_PY_UTIMEQ

View file

@ -31,9 +31,9 @@ typedef struct _mp_obj_decompio_t {
} mp_obj_decompio_t; } mp_obj_decompio_t;
STATIC int read_src_stream(TINF_DATA *data) { STATIC int read_src_stream(TINF_DATA *data) {
byte *p = (void*)data; byte *p = (void *)data;
p -= offsetof(mp_obj_decompio_t, decomp); p -= offsetof(mp_obj_decompio_t, decomp);
mp_obj_decompio_t *self = (mp_obj_decompio_t*)p; mp_obj_decompio_t *self = (mp_obj_decompio_t *)p;
const mp_stream_p_t *stream = mp_get_stream(self->src_stream); const mp_stream_p_t *stream = mp_get_stream(self->src_stream);
int err; int err;
@ -73,7 +73,7 @@ STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, cons
} else if (dict_opt >= 0) { } else if (dict_opt >= 0) {
dict_opt = uzlib_zlib_parse_header(&o->decomp); dict_opt = uzlib_zlib_parse_header(&o->decomp);
if (dict_opt < 0) { if (dict_opt < 0) {
header_error: header_error:
mp_raise_ValueError(translate("compression header")); mp_raise_ValueError(translate("compression header"));
} }
dict_sz = 1 << dict_opt; dict_sz = 1 << dict_opt;
@ -92,7 +92,7 @@ STATIC mp_uint_t decompio_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *er
} }
o->decomp.dest = buf; o->decomp.dest = buf;
o->decomp.dest_limit = (unsigned char*)buf+size; o->decomp.dest_limit = (unsigned char *)buf + size;
int st = uzlib_uncompress_chksum(&o->decomp); int st = uzlib_uncompress_chksum(&o->decomp);
if (st == TINF_DONE) { if (st == TINF_DONE) {
o->eof = true; o->eof = true;
@ -101,7 +101,7 @@ STATIC mp_uint_t decompio_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *er
*errcode = MP_EINVAL; *errcode = MP_EINVAL;
return MP_STREAM_ERROR; return MP_STREAM_ERROR;
} }
return o->decomp.dest - (byte*)buf; return o->decomp.dest - (byte *)buf;
} }
STATIC const mp_rom_map_elem_t decompio_locals_dict_table[] = { STATIC const mp_rom_map_elem_t decompio_locals_dict_table[] = {
@ -122,7 +122,7 @@ STATIC const mp_obj_type_t decompio_type = {
.name = MP_QSTR_DecompIO, .name = MP_QSTR_DecompIO,
.make_new = decompio_make_new, .make_new = decompio_make_new,
.protocol = &decompio_stream_p, .protocol = &decompio_stream_p,
.locals_dict = (void*)&decompio_locals_dict, .locals_dict = (void *)&decompio_locals_dict,
}; };
STATIC mp_obj_t mod_uzlib_decompress(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t mod_uzlib_decompress(size_t n_args, const mp_obj_t *args) {
@ -138,7 +138,7 @@ STATIC mp_obj_t mod_uzlib_decompress(size_t n_args, const mp_obj_t *args) {
byte *dest_buf = m_new(byte, dest_buf_size); byte *dest_buf = m_new(byte, dest_buf_size);
decomp->dest = dest_buf; decomp->dest = dest_buf;
decomp->dest_limit = dest_buf+dest_buf_size; decomp->dest_limit = dest_buf + dest_buf_size;
DEBUG_printf("uzlib: Initial out buffer: " UINT_FMT " bytes\n", decomp->destSize); DEBUG_printf("uzlib: Initial out buffer: " UINT_FMT " bytes\n", decomp->destSize);
decomp->source = bufinfo.buf; decomp->source = bufinfo.buf;
decomp->source_limit = (unsigned char *)bufinfo.buf + bufinfo.len; decomp->source_limit = (unsigned char *)bufinfo.buf + bufinfo.len;
@ -173,7 +173,7 @@ STATIC mp_obj_t mod_uzlib_decompress(size_t n_args, const mp_obj_t *args) {
mp_uint_t final_sz = decomp->dest - dest_buf; mp_uint_t final_sz = decomp->dest - dest_buf;
DEBUG_printf("uzlib: Resizing from " UINT_FMT " to final size: " UINT_FMT " bytes\n", dest_buf_size, final_sz); DEBUG_printf("uzlib: Resizing from " UINT_FMT " to final size: " UINT_FMT " bytes\n", dest_buf_size, final_sz);
dest_buf = (byte*)m_renew(byte, dest_buf, dest_buf_size, final_sz); dest_buf = (byte *)m_renew(byte, dest_buf, dest_buf_size, final_sz);
mp_obj_t res = mp_obj_new_bytearray_by_ref(final_sz, dest_buf); mp_obj_t res = mp_obj_new_bytearray_by_ref(final_sz, dest_buf);
m_del_obj(TINF_DATA, decomp); m_del_obj(TINF_DATA, decomp);
return res; return res;
@ -193,7 +193,7 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_uzlib_globals, mp_module_uzlib_globals_tab
const mp_obj_module_t mp_module_uzlib = { const mp_obj_module_t mp_module_uzlib = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_uzlib_globals, .globals = (mp_obj_dict_t *)&mp_module_uzlib_globals,
}; };
// Source files #include'd here to make sure they're compiled in // Source files #include'd here to make sure they're compiled in

View file

@ -14,7 +14,6 @@
#include "py/mphal.h" #include "py/mphal.h"
#endif #endif
#include "extmod/modwebsocket.h" #include "extmod/modwebsocket.h"
#include "genhdr/mpversion.h"
#if MICROPY_PY_WEBREPL #if MICROPY_PY_WEBREPL
@ -127,7 +126,7 @@ STATIC void handle_op(mp_obj_webrepl_t *self) {
open_args[1] = MP_OBJ_NEW_QSTR(MP_QSTR_wb); open_args[1] = MP_OBJ_NEW_QSTR(MP_QSTR_wb);
} }
self->cur_file = mp_builtin_open(2, open_args, (mp_map_t*)&mp_const_empty_map); self->cur_file = mp_builtin_open(2, open_args, (mp_map_t *)&mp_const_empty_map);
#if 0 #if 0
struct mp_stream_seek_t seek = { .offset = self->hdr.offset, .whence = 0 }; struct mp_stream_seek_t seek = { .offset = self->hdr.offset, .whence = 0 };
@ -161,13 +160,13 @@ STATIC mp_uint_t _webrepl_read(mp_obj_t self_in, void *buf, mp_uint_t size, int
mp_obj_webrepl_t *self = self_in; mp_obj_webrepl_t *self = self_in;
const mp_stream_p_t *sock_stream = mp_get_stream(self->sock); const mp_stream_p_t *sock_stream = mp_get_stream(self->sock);
mp_uint_t out_sz = sock_stream->read(self->sock, buf, size, errcode); mp_uint_t out_sz = sock_stream->read(self->sock, buf, size, errcode);
//DEBUG_printf("webrepl: Read %d initial bytes from websocket\n", out_sz); // DEBUG_printf("webrepl: Read %d initial bytes from websocket\n", out_sz);
if (out_sz == 0 || out_sz == MP_STREAM_ERROR) { if (out_sz == 0 || out_sz == MP_STREAM_ERROR) {
return out_sz; return out_sz;
} }
if (self->state == STATE_PASSWD) { if (self->state == STATE_PASSWD) {
char c = *(char*)buf; char c = *(char *)buf;
if (c == '\r' || c == '\n') { if (c == '\r' || c == '\n') {
self->hdr.fname[self->data_to_recv] = 0; self->hdr.fname[self->data_to_recv] = 0;
DEBUG_printf("webrepl: entered password: %s\n", self->hdr.fname); DEBUG_printf("webrepl: entered password: %s\n", self->hdr.fname);
@ -195,8 +194,8 @@ STATIC mp_uint_t _webrepl_read(mp_obj_t self_in, void *buf, mp_uint_t size, int
DEBUG_printf("webrepl: received bin data, hdr_to_recv: %d, data_to_recv=%d\n", self->hdr_to_recv, self->data_to_recv); DEBUG_printf("webrepl: received bin data, hdr_to_recv: %d, data_to_recv=%d\n", self->hdr_to_recv, self->data_to_recv);
if (self->hdr_to_recv != 0) { if (self->hdr_to_recv != 0) {
char *p = (char*)&self->hdr + sizeof(self->hdr) - self->hdr_to_recv; char *p = (char *)&self->hdr + sizeof(self->hdr) - self->hdr_to_recv;
*p++ = *(char*)buf; *p++ = *(char *)buf;
if (--self->hdr_to_recv != 0) { if (--self->hdr_to_recv != 0) {
mp_uint_t hdr_sz = sock_stream->read(self->sock, p, self->hdr_to_recv, errcode); mp_uint_t hdr_sz = sock_stream->read(self->sock, p, self->hdr_to_recv, errcode);
if (hdr_sz == MP_STREAM_ERROR) { if (hdr_sz == MP_STREAM_ERROR) {
@ -217,7 +216,7 @@ STATIC mp_uint_t _webrepl_read(mp_obj_t self_in, void *buf, mp_uint_t size, int
if (self->data_to_recv != 0) { if (self->data_to_recv != 0) {
static byte filebuf[512]; static byte filebuf[512];
filebuf[0] = *(byte*)buf; filebuf[0] = *(byte *)buf;
mp_uint_t buf_sz = 1; mp_uint_t buf_sz = 1;
if (--self->data_to_recv != 0) { if (--self->data_to_recv != 0) {
size_t to_read = MIN(sizeof(filebuf) - 1, self->data_to_recv); size_t to_read = MIN(sizeof(filebuf) - 1, self->data_to_recv);
@ -321,7 +320,7 @@ STATIC const mp_obj_type_t webrepl_type = {
.name = MP_QSTR__webrepl, .name = MP_QSTR__webrepl,
.make_new = webrepl_make_new, .make_new = webrepl_make_new,
.protocol = &webrepl_stream_p, .protocol = &webrepl_stream_p,
.locals_dict = (mp_obj_dict_t*)&webrepl_locals_dict, .locals_dict = (mp_obj_dict_t *)&webrepl_locals_dict,
}; };
STATIC const mp_rom_map_elem_t webrepl_module_globals_table[] = { STATIC const mp_rom_map_elem_t webrepl_module_globals_table[] = {
@ -334,7 +333,7 @@ STATIC MP_DEFINE_CONST_DICT(webrepl_module_globals, webrepl_module_globals_table
const mp_obj_module_t mp_module_webrepl = { const mp_obj_module_t mp_module_webrepl = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&webrepl_module_globals, .globals = (mp_obj_dict_t *)&webrepl_module_globals,
}; };
#endif // MICROPY_PY_WEBREPL #endif // MICROPY_PY_WEBREPL

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