diff --git a/.github/workflows/arduino-release.yml b/.github/workflows/arduino-release.yml
new file mode 100644
index 00000000..9041750b
--- /dev/null
+++ b/.github/workflows/arduino-release.yml
@@ -0,0 +1,242 @@
+name: Arduino CI Build (2 of 4) Release Arduino wolfSSL for Local Examples
+
+# TODO - implement this once future wolfSSL is released
+#
+# Known to fail on current 5.8.2 wolfSSL Arduino Release
+#
+# See ardduino.yml - Arduino CI Build (3 of 4) Latest wolfSSL for Local Examples
+
+#
+# Test local Arduino examples with published Arduino wolfssl
+#
+# These 4 workflows across 3 repos are interdependent for the current $REPO_OWNER:
+#
+# Arduino CI Build 1: https://github.com/$REPO_OWNER/wolfssl # /.github/workflows/arduino.yml
+# - Builds Arduino library from local clone of wolfssl master branch
+# - Fetches examples from https://github.com/$REPO_OWNER/wolfssl-examples
+#
+# THIS Arduino CI Build 2: https://github.com/$REPO_OWNER/wolfssl-examples # /.github/workflows/arduino-release.yml
+# - Tests examples based on latest published release of Arduino library, NOT latest on wolfssl github.
+# - Should be identical to Arduino CI Build 3 in every way but wolfssl install.
+# - Copies only compile script from wolfssl-examples
+# - Builds local examples
+# - No other repos used
+#
+# Arduino CI Build 3: https://github.com/$REPO_OWNER/wolfssl-examples # /.github/workflows/arduino.yml
+# - Fetches current wolfSSL from https://github.com/$REPO_OWNER/wolfssl
+# - Creates an updated Arduino library
+# - Compiles local examples
+# - Contains the source of `compile-all-examples.sh` and respective board-list.txt
+#
+# Arduino CI Build 4: https://github.com/$REPO_OWNER/Arduino-wolfssl # /.github/workflows/arduino.yml
+# - Assembles and installs an updated Arduino wolfssl library from LOCAL wolfssl master source
+# - Copies only compile script copied from wolfssl-examples
+# - Builds local examples
+# - No other repos used
+#
+#
+# ** NOTE TO MAINTAINERS **
+#
+# Consider using winmerge or similar tool to keep the 4 arduino[-release].yml files in relative sync.
+# Although there are some specific differences, most of the contents are otherwise identical.
+#
+# See https://github.com/wolfSSL/Arduino-wolfSSL
+#
+# To test locally:
+# cd [your WOLFSSL_ROOT], e.g. cd /mnt/c/workspace/wolfssl-$USER
+# [optional checkout] e.g. git checkout tags/v5.8.2-stable
+# pushd ./IDE/ARDUINO
+# export ARDUINO_ROOT="$HOME/Arduino/libraries"
+# ./wolfssl-arduino.sh INSTALL
+# cd [your WOLFSSL_EXAMPLES_ROOT] e.g. /mnt/c/workspace/wolfssl-examples-$USER
+#
+
+# START OF COMMON SECTION
+on:
+ push:
+ branches: [ '**', 'master', 'main', 'release/**' ]
+ paths:
+ - 'Arduino/**'
+ - '!Arduino/sketches/board_list.txt' # Not triggered on arduino.yml file. TODO remove this line after next Arduino wolfssl release
+ - '.github/workflows/arduino-release.yml'
+ pull_request:
+ branches: [ '**' ]
+ paths:
+ - 'Arduino/**'
+ - '!Arduino/sketches/board_list.txt' # Not triggered on arduino.yml file. TODO remove this line after next Arduino wolfssl release
+ - '.github/workflows/arduino-release.yml'
+ workflow_dispatch:
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+# END OF COMMON SECTION
+
+jobs:
+ build:
+ # if: github.repository_owner == 'wolfssl'
+ runs-on: ubuntu-latest
+ env:
+ REPO_OWNER: ${{ github.repository_owner }}
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+
+ - name: Install Arduino CLI
+ run: |
+ # Script to fetch and run install.sh from arduino/arduino-cli
+
+ # The install script will test to see if the recently installed apps in in the path
+ # So set it up in advance:
+ mkdir -p "${PWD}/bin"
+ echo "${PWD}/bin" >> $GITHUB_PATH
+
+ # Sets the install directory to a consistent path at the repo root.
+ ROOT_BIN="$GITHUB_WORKSPACE/bin"
+
+ # Ensures that BINDIR exists before the installer runs
+ mkdir -p "$ROOT_BIN"
+
+ # Save as a lobal environment variable
+ echo "$ROOT_BIN" >> "$GITHUB_PATH"
+
+ # Download and run install script from Arduino:
+ # -S show errors; -L follow redirects; -v Verbose
+ set +e # don't abort on error
+ set -o pipefail
+
+ curl -vSL --retry 5 --retry-delay 10 \
+ https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh \
+ | sh -x
+ rc=$?
+ c_rc=${PIPESTATUS[0]} # curl's exit code
+ s_rc=${PIPESTATUS[1]} # sh's exit code
+
+ set -e # restore default abort-on-error
+
+ # If there was a curl error, we have our own local copy that is more reliable and can add our own debugging
+ if [ "$rc" -ne 0 ]; then
+ echo "Primary install failed: curl=$c_rc, sh=$s_rc. Falling back..." >&2
+ echo "Using local copy of arduino_install.sh"
+ pushd ./Arduino/sketches
+ chmod +x ./arduino_install.sh
+
+ # Mimic curl install, does not use current directory:
+ BINDIR="$ROOT_BIN" sh -x ./arduino_install.sh
+ popd
+ else
+ echo "Alternative install script not needed."
+ fi
+
+ - name: Confirm Arduino CLI install
+ run: arduino-cli version
+
+ - name: Setup Arduino CLI
+ run: |
+ arduino-cli config init
+ arduino-cli core update-index
+ arduino-cli config add board_manager.additional_urls https://www.pjrc.com/teensy/package_teensy_index.json
+ arduino-cli core update-index
+ arduino-cli config add board_manager.additional_urls https://arduino.esp8266.com/stable/package_esp8266com_index.json
+ arduino-cli core update-index
+ arduino-cli core install esp32:esp32 # ESP32
+ arduino-cli core install arduino:avr # Arduino Uno, Mega, Nano
+ arduino-cli core install arduino:sam # Arduino Due
+ arduino-cli core install arduino:samd # Arduino Zero
+ arduino-cli core install teensy:avr # PJRC Teensy
+ arduino-cli core install esp8266:esp8266 # ESP8266
+ arduino-cli core install arduino:mbed_nano # nanorp2040connect
+ arduino-cli core install arduino:mbed_portenta # portenta_h7_m7
+ arduino-cli core install arduino:mbed_edge
+ # sudo "/home/$USER/.arduino15/packages/arduino/hardware/mbed_nano/4.2.4/post_install.sh"
+ arduino-cli core install arduino:renesas_uno
+ arduino-cli lib install "ArduinoJson" # Example dependency
+ arduino-cli lib install "WiFiNINA" # ARDUINO_SAMD_NANO_33_IOT
+ arduino-cli lib install "Ethernet" # Install Ethernet library
+ arduino-cli lib install "Bridge" # Pseudo-network for things like arduino:samd:tian
+
+ - name: Set job environment variables
+ run: |
+ # Script to assign some common environment variables after everything is installed
+
+ ICON_OK=$(printf "\xE2\x9C\x85")
+ ICON_FAIL=$(printf "\xE2\x9D\x8C")
+
+ echo "GITHUB_WORK=$(realpath "$GITHUB_WORKSPACE/../..")" >> "$GITHUB_ENV"
+ echo "ARDUINO_ROOT=$(realpath "$HOME/Arduino/libraries")" >> "$GITHUB_ENV"
+
+ # Show repo-specific location of examples:
+ echo "WOLFSSL_EXAMPLES_ROOT=$(realpath "./Arduino/sketches")" >> "$GITHUB_ENV"
+
+ # Show predefined summary:
+ echo "GITHUB_WORKSPACE = $GITHUB_WORKSPACE"
+
+ # Show assigned build:env values (e.g. "wolfssl", "gojimmpi" or other owners):
+ echo "REPO_OWNER = $REPO_OWNER"
+
+ # Show our custom values:
+ echo "GITHUB_WORK = $GITHUB_WORK"
+ echo "ARDUINO_ROOT = $ARDUINO_ROOT"
+
+ # WOLFSSL_EXAMPLES_ROOT is the report root, not example location
+ echo "WOLFSSL_EXAMPLES_ROOT = $WOLFSSL_EXAMPLES_ROOT"
+
+ - name: Show wolfssl-examples
+ run: |
+ # The examples are local in this wolfssl-example repo, but should have been copied to library, above
+ ls ./Arduino/sketches
+
+ # end Show wolfssl-examples
+
+ # - name: Shallow clone wolfssl
+ #
+ # not used here, we'll install with arduino-cli in next step
+
+ #
+ # These comments are mainly here to help align with arduino.yml source side-by-side sync
+ #
+ # end wolfssl source
+
+ - name: Install wolfSSL Published Arduino library
+
+ run: |
+ # Install wolfssl via latest published version with arduino-cli lib install
+
+
+ arduino-cli lib install "wolfSSL"
+
+ # End Install wolfSSL Arduino library
+
+ - name: List installed Arduino libraries
+ run: arduino-cli lib list
+
+ # This will fail with Arduino published wolfSSL v5.7.6 and older
+ # as the examples moved. See https://github.com/wolfSSL/wolfssl/pull/8514
+ #
+ - name: Compile Arduino Sketches for Various Boards
+ run: |
+ # Call the compile-all-examples.sh script to compile all the examples for each of the fqbn names in the local copy of board_list.txt
+
+ echo "Current directory = $PWD"
+ echo "ARDUINO_ROOT = $ARDUINO_ROOT"
+ echo "WOLFSSL_EXAMPLES_ROOT = $WOLFSSL_EXAMPLES_ROOT"
+
+ pushd ./Arduino/sketches
+ chmod +x ./compile-all-examples.sh
+
+ # The script expects all the examples to be in the current directory.
+ # So copy from local directory to newly instlled wolfssl arduino library to compile there.
+ cp ./compile-all-examples.sh "$ARDUINO_ROOT/wolfssl/examples/compile-all-examples.sh"
+ cp ./board_list.txt "$ARDUINO_ROOT/wolfssl/examples/board_list.txt"
+
+ # TODO Use standard board_list.txt after next release of wolfSSL
+ cp ./board_list_v5.8.2.txt "$ARDUINO_ROOT/wolfssl/examples/board_list_v5.8.2.txt"
+
+ # Compile the Arduino library examples in-place
+ pushd "$ARDUINO_ROOT/wolfssl/examples/"
+ echo "PWD=$PWD"
+ ./compile-all-examples.sh board_list_v5.8.2.txt
+ popd
+ popd
+
+ # End Compile Arduino Sketches for Various Boards
diff --git a/.github/workflows/arduino.yml b/.github/workflows/arduino.yml
index 72356099..3b9933a5 100644
--- a/.github/workflows/arduino.yml
+++ b/.github/workflows/arduino.yml
@@ -1,13 +1,64 @@
-name: Arduino CI Build
+name: Arduino CI Build (3 of 4) Latest wolfSSL for Local Examples
+#
+# Test local Arduino examples with clone of LATEST github master branch wolfssl
+#
+# These 4 workflows across 3 repos are interdependent for the current $REPO_OWNER:
+#
+# Arduino CI Build 1: https://github.com/$REPO_OWNER/wolfssl # /.github/workflows/arduino.yml
+# - Builds Arduino library from local clone of wolfssl master branch
+# - Fetches examples from https://github.com/$REPO_OWNER/wolfssl-examples
+#
+# Arduino CI Build 2: https://github.com/$REPO_OWNER/wolfssl-examples # /.github/workflows/arduino-release.yml
+# - Tests examples based on latest published release of Arduino library, NOT latest on wolfssl github.
+# - Should be identical to Arduino CI Build 3 in every way but wolfssl install.
+# - Copies only compile script from wolfssl-examples
+# - Builds local examples
+# - No other repos used
+#
+# THIS Arduino CI Build 3: https://github.com/$REPO_OWNER/wolfssl-examples # /.github/workflows/arduino.yml
+# - Fetches current wolfSSL from https://github.com/$REPO_OWNER/wolfssl
+# - Creates an updated Arduino library
+# - Compiles local examples
+# - Contains the source of `compile-all-examples.sh` and respective board-list.txt
+#
+# Arduino CI Build 4: https://github.com/$REPO_OWNER/Arduino-wolfssl # /.github/workflows/arduino.yml
+# - Assembles and installs an updated Arduino wolfssl library from LOCAL wolfssl master source
+# - Copies only compile script copied from wolfssl-examples
+# - Builds local examples
+# - No other repos used
+#
+#
+# ** NOTE TO MAINTAINERS **
+#
+# Consider using winmerge or similar tool to keep the 4 arduino[-release].yml files in relative sync.
+# Although there are some specific differences, most of the contents are otherwise identical.
+#
# See https://github.com/wolfSSL/Arduino-wolfSSL
+#
+# To test locally:
+# cd [your WOLFSSL_ROOT], e.g. cd /mnt/c/workspace/wolfssl-$USER
+# [optional checkout] e.g. git checkout tags/v5.8.2-stable
+# pushd ./IDE/ARDUINO
+# export ARDUINO_ROOT="$HOME/Arduino/libraries"
+# ./wolfssl-arduino.sh INSTALL
+# cd [your WOLFSSL_EXAMPLES_ROOT] e.g. /mnt/c/workspace/wolfssl-examples-$USER
+#
# START OF COMMON SECTION
on:
push:
- branches: [ 'master', 'main', 'release/**' ]
+ branches: [ '**', 'master', 'main', 'release/**' ]
+ paths:
+ - 'Arduino/**'
+ - '!Arduino/sketches/board_list_v5.8.2.txt' # Not triggered on arduino-release.yml file. TODO remove this line after next Arduino wolfssl release
+ - '.github/workflows/arduino.yml'
pull_request:
- branches: [ '*' ]
+ branches: [ '**' ]
+ paths:
+ - 'Arduino/**'
+ - '!Arduino/sketches/board_list_v5.8.2.txt' # Not triggered on arduino-release.yml file. TODO remove this line after next Arduino wolfssl release
+ - '.github/workflows/arduino.yml'
workflow_dispatch:
concurrency:
@@ -17,16 +68,62 @@ concurrency:
jobs:
build:
- if: github.repository_owner == 'wolfssl'
+ # if: github.repository_owner == 'wolfssl'
runs-on: ubuntu-latest
+ env:
+ REPO_OWNER: ${{ github.repository_owner }}
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Install Arduino CLI
run: |
- curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sh
- echo "$(pwd)/bin" >> $GITHUB_PATH
+ # Script to fetch and run install.sh from arduino/arduino-cli
+
+ # The install script will test to see if the recently installed apps in in the path
+ # So set it up in advance:
+ mkdir -p "${PWD}/bin"
+ echo "${PWD}/bin" >> $GITHUB_PATH
+
+ # Sets the install directory to a consistent path at the repo root.
+ ROOT_BIN="$GITHUB_WORKSPACE/bin"
+
+ # Ensures that BINDIR exists before the installer runs
+ mkdir -p "$ROOT_BIN"
+
+ # Save as a lobal environment variable
+ echo "$ROOT_BIN" >> "$GITHUB_PATH"
+
+ # Download and run install script from Arduino:
+ # -S show errors; -L follow redirects; -v Verbose
+ set +e # don't abort on error
+ set -o pipefail
+
+ curl -vSL --retry 5 --retry-delay 10 \
+ https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh \
+ | sh -x
+ rc=$?
+ c_rc=${PIPESTATUS[0]} # curl's exit code
+ s_rc=${PIPESTATUS[1]} # sh's exit code
+
+ set -e # restore default abort-on-error
+
+ # If there was a curl error, we have our own local copy that is more reliable and can add our own debugging
+ if [ "$rc" -ne 0 ]; then
+ echo "Primary install failed: curl=$c_rc, sh=$s_rc. Falling back..." >&2
+ echo "Using local copy of arduino_install.sh"
+ pushd ./Arduino/sketches
+ chmod +x ./arduino_install.sh
+
+ # Mimic curl install, does not use current directory:
+ BINDIR="$ROOT_BIN" sh -x ./arduino_install.sh
+ popd
+ else
+ echo "Alternative install script not needed."
+ fi
+
+ - name: Confirm Arduino CLI install
+ run: arduino-cli version
- name: Setup Arduino CLI
run: |
@@ -36,133 +133,151 @@ jobs:
arduino-cli core update-index
arduino-cli config add board_manager.additional_urls https://arduino.esp8266.com/stable/package_esp8266com_index.json
arduino-cli core update-index
- arduino-cli core install esp32:esp32 # ESP32
- arduino-cli core install arduino:avr # Arduino Uno, Mega, Nano
- arduino-cli core install arduino:sam # Arduino Due
- arduino-cli core install arduino:samd # Arduino Zero
- arduino-cli core install teensy:avr # PJRC Teensy
- arduino-cli core install esp8266:esp8266 # ESP8266
- arduino-cli lib install "ArduinoJson" # Example dependency
- arduino-cli lib install "WiFiNINA" # ARDUINO_SAMD_NANO_33_IOT
- arduino-cli lib install "Ethernet" # Install Ethernet library
-
- # arduino-cli lib install "wolfSSL" # Install wolfSSL library from Arduino
-
- # Install current wolfSSL as an Arduino library:
+ arduino-cli core install esp32:esp32 # ESP32
+ arduino-cli core install arduino:avr # Arduino Uno, Mega, Nano
+ arduino-cli core install arduino:sam # Arduino Due
+ arduino-cli core install arduino:samd # Arduino Zero
+ arduino-cli core install teensy:avr # PJRC Teensy
+ arduino-cli core install esp8266:esp8266 # ESP8266
+ arduino-cli core install arduino:mbed_nano # nanorp2040connect
+ arduino-cli core install arduino:mbed_portenta # portenta_h7_m7
+ arduino-cli core install arduino:mbed_edge
+ # sudo "/home/$USER/.arduino15/packages/arduino/hardware/mbed_nano/4.2.4/post_install.sh"
+ arduino-cli core install arduino:renesas_uno
+ arduino-cli lib install "ArduinoJson" # Example dependency
+ arduino-cli lib install "WiFiNINA" # ARDUINO_SAMD_NANO_33_IOT
+ arduino-cli lib install "Ethernet" # Install Ethernet library
+ arduino-cli lib install "Bridge" # Pseudo-network for things like arduino:samd:tian
+
+ - name: Set job environment variables
+ run: |
+ # Script to assign some common environment variables after everything is installed
+
+ ICON_OK=$(printf "\xE2\x9C\x85")
+ ICON_FAIL=$(printf "\xE2\x9D\x8C")
+
+ echo "GITHUB_WORK=$(realpath "$GITHUB_WORKSPACE/../..")" >> "$GITHUB_ENV"
+ echo "ARDUINO_ROOT=$(realpath "$HOME/Arduino/libraries")" >> "$GITHUB_ENV"
+
+ # Show repo-specific location of examples:
+ echo "WOLFSSL_EXAMPLES_ROOT=$(realpath "./Arduino/sketches")" >> "$GITHUB_ENV"
+
+ # Show predefined summary:
+ echo "GITHUB_WORKSPACE = $GITHUB_WORKSPACE"
+
+ # Show assigned build:env values (e.g. "wolfssl", "gojimmpi" or other owners):
+ echo "REPO_OWNER = $REPO_OWNER"
+
+ # Show our custom values:
+ echo "GITHUB_WORK = $GITHUB_WORK"
+ echo "ARDUINO_ROOT = $ARDUINO_ROOT"
+
+ # WOLFSSL_EXAMPLES_ROOT is the report root, not example location
+ echo "WOLFSSL_EXAMPLES_ROOT = $WOLFSSL_EXAMPLES_ROOT"
+
+ - name: Show wolfssl-examples
+ run: |
+ # The examples are local in this wolfssl-example repo, but should have been copied to library, above
+ ls ./Arduino/sketches
+
+ # end Show wolfssl-examples
+
- name: Shallow clone wolfssl
run: |
- git clone --depth 1 https://github.com/wolfSSL/wolfssl.git
- echo "Checking Arduino library directories..."
+ # Clone the wolfssl to use for example build
+
+ # TODO remove after merge
+ REPO_OWNER=gojimmypi
+ # End TODO
+
+ git clone --depth 1 https://github.com/$REPO_OWNER/wolfssl.git
+
+ # Assign your PR branch for testing here:
+ THIS_PR_BRANCH=""
+
+ echo "REPO_OWNER=$REPO_OWNER"
+
+ # TODO remove after merge
+ # A user-specific branch assignment
+ if [[ "$REPO_OWNER" == "gojimmypi" ]]; then
+ THIS_PR_BRANCH="pr-arduino-testing"
+ else
+ echo "unexpected repo owner!"
+ fi
+ # END TODO
+
+ # If a branch is assigned for current repo user, checkout
+ if [ -z "$THIS_PR_BRANCH" ]; then
+ echo "Assign your PR branch name for testing"
+ else
+ # fetch open PR changes
+ pushd wolfssl
+ git remote add $REPO_OWNER https://github.com/$REPO_OWNER/wolfssl.git
+ git fetch --depth 1 "$REPO_OWNER" "$THIS_PR_BRANCH"
+ git checkout "$THIS_PR_BRANCH"
+ popd
+ fi
+ # end wolfssl source
- name: Install wolfSSL Arduino library
run: |
- pushd wolfssl/IDE/ARDUINO
+ # Install wolfssl via wolfssl-arduino.sh install script
+
+ # Even though the examples are in this library, we'll test as installed for library publishing.
+ # When WOLFSSL_EXAMPLES_ROOT is set, the examples will be copied from that path to the published library.
+ # WOLFSSL_EXAMPLES_ROOT is the repo root, not example directory location (./Arduino/sketches) within.
+ export WOLFSSL_EXAMPLES_ROOT=$(realpath "./")
- # Set default ARDUINO_ROOT. TODO: once script is updated, this should be removed.
- export ARDUINO_ROOT="$HOME/Arduino/libraries"
+ # Confirm ARDUINO_ROOT to install the wolfSSL library, see above "Set job environment variables"
+ echo "PWD = $PWD"
+ echo "ARDUINO_ROOT = $ARDUINO_ROOT"
+ echo "WOLFSSL_EXAMPLES_ROOT = $WOLFSSL_EXAMPLES_ROOT"
+ ls ./Arduino/sketches
- bash wolfssl-arduino.sh INSTALL # Install wolfSSL library
+ if [ -z "$WOLFSSL_EXAMPLES_ROOT" ]; then
+ echo "$ICON_FAIL ERROR: Tests should be performed on in-place examples. WOLFSSL_EXAMPLES_ROOT is blank"
+ fi
+
+ # The install script is in the wolfssl repo, in /IDE/ARDUINO directory.
+ # Only explicit source code is copied to the Arduino library.
+ # Edit wolfssl-arduino.sh as needed for new examples.
+ pushd ./wolfssl/IDE/ARDUINO
+ chmod +x ./wolfssl-arduino.sh
+ bash ./wolfssl-arduino.sh INSTALL # Install wolfSSL as Arduino library in ARDUINO_ROOT
popd
+ echo "Examples installed in $ARDUINO_ROOT/wolfssl/examples"
+ ls "$ARDUINO_ROOT/wolfssl/examples" -al
+
+ # End Install wolfSSL Arduino library
+
+ - name: List installed Arduino libraries
+ run: arduino-cli lib list
+
# This will fail with Arduino published wolfSSL v5.7.6 and older
- # See https://github.com/wolfSSL/wolfssl/pull/8514
- # Pending: "arduino:sam:arduino_due_x"
- - name: Compile Arduino Sketches for various boards
+ # as the examples moved. See https://github.com/wolfSSL/wolfssl/pull/8514
+ #
+ - name: Compile Arduino Sketches for Various Boards
run: |
- set +e
- SUCCESS=true
- for BOARD in "arduino:avr:uno" "esp32:esp32:esp32" "arduino:avr:mega" "arduino:avr:nano" "arduino:samd:arduino_zero_native" "esp8266:esp8266:generic" "teensy:avr:teensy40"; do
- echo "Compiling for $BOARD"
- for EXAMPLE in $(find Arduino/sketches -mindepth 1 -maxdepth 1 -type d); do
-
- # skip known no-wifi SAMD boards
- if [[ "$BOARD" =~ "arduino:samd:arduino_zero_native" && ( "$EXAMPLE" =~ "wolfssl_server" || "$EXAMPLE" =~ "wolfssl_client" || "$EXAMPLE" =~ "test" ) ]]; then
- echo "Skipping $EXAMPLE for $BOARD (No WiFi support)"
- continue
- fi
-
- # skip known no-wifi AVR boards
- if [[ "$BOARD" =~ ^arduino:avr:(uno|mega|nano)$ ]] && \
- ( [[ "$EXAMPLE" =~ "wolfssl_server" ]] || \
- [[ "$EXAMPLE" =~ "wolfssl_client" ]] || \
- [[ "$EXAMPLE" =~ "test" ]] ); then
- echo "Skipping $EXAMPLE for $BOARD (No WiFi support)"
- continue
- fi
-
- # skip known no-wifi teensy AVR boards
- if [[ "$BOARD" =~ ^teensy:avr:(teensy40)$ ]] && \
- ( [[ "$EXAMPLE" =~ "wolfssl_server" ]] || \
- [[ "$EXAMPLE" =~ "wolfssl_client" ]] || \
- [[ "$EXAMPLE" =~ "test" ]] ); then
- echo "Skipping $EXAMPLE for $BOARD (needs ethernet update)"
- continue
- fi
-
- # skip examples other than template and version for known tiny memory boards
- if [[ "$BOARD" =~ ( "arduino:avr:uno"|"arduino:avr:nano" ) && ( "$EXAMPLE" != "template" ) && ( "$EXAMPLE" != "wolfssl_version" ) ]]; then
- echo "Skipping $EXAMPLE for $BOARD (memory limited)"
- continue
- fi
-
- # TODO: new template known to fail. Fixed in https://github.com/wolfSSL/wolfssl/pull/8514
- if [[ "$EXAMPLE" =~ "Arduino/sketches/template" ]]; then
- echo "Skipping $EXAMPLE for $BOARD (needs code update. see wolfssl/pull/8514)"
- continue
- fi
-
- # TODO: new wolfssl_AES_CTR known to fail. Fixed in https://github.com/wolfSSL/wolfssl/pull/8514
- if [[ "$EXAMPLE" =~ "Arduino/sketches/wolfssl_AES_CTR" ]]; then
- echo "Skipping $EXAMPLE for $BOARD (needs updated user_settings.h - see wolfssl/pull/8514)"
- continue
- fi
-
- # TODO skip Compiling Arduino/sketches/wolfssl_version for arduino:avr:mega
- if [[ "$BOARD" =~ "arduino:avr:mega" && "$EXAMPLE" =~ "Arduino/sketches/wolfssl_version" ]]; then
- echo "Skipping $EXAMPLE for $BOARD (needs updated code - see wolfssl/pull/8514)"
- continue
- fi
-
- # TODO skip Compiling Arduino/sketches/wolfssl_version for arduino:avr:uno
- if [[ "$BOARD" =~ ^arduino:avr:(uno|mega|nano)$ ]] && \
- ( [[ "$EXAMPLE" =~ "wolfssl_version" ]] ); then
- echo "Skipping $EXAMPLE for $BOARD (fixed in see wolfssl/pull/8514)"
- continue
- fi
-
- if [[ "$BOARD" =~ "arduino:avr:uno" && "$EXAMPLE" =~ "Arduino/sketches/wolfssl_version" ]]; then
- echo "Skipping $EXAMPLE for $BOARD (needs updated code - see wolfssl/pull/8514)"
- continue
- fi
-
- # TODO skip ESP8266
- if [[ "$BOARD" =~ "esp8266:esp8266:generic" ]]; then
- echo "Skipping $EXAMPLE for $BOARD (needs testing)"
- continue
- fi
-
- # If otherwise not excluded, compile this $EXAMPLE for this $BOARD
- echo "Compiling $EXAMPLE for $BOARD"
- arduino-cli compile --fqbn $BOARD "$EXAMPLE"
- EXIT_CODE=$?
- if [ "$EXIT_CODE" -ne 0 ]; then
- echo "❌ Compilation failed for $EXAMPLE on $BOARD (Exit code: $EXIT_CODE)"
- SUCCESS=false
- else
- echo "✅ Compilation succeeded for $EXAMPLE on $BOARD"
- fi
- done
- done
-
- if [ "$SUCCESS" = true ]; then
- echo "✅ All sketches compiled successfully!"
- else
- echo "❌ One or more sketches failed to compile."
- exit 1
- fi
+ # Call the compile-all-examples.sh script to compile all the examples for each of the fqbn names in the local copy of board_list.txt
+
+ echo "Current directory = $PWD"
+ echo "ARDUINO_ROOT = $ARDUINO_ROOT"
+ echo "WOLFSSL_EXAMPLES_ROOT = $WOLFSSL_EXAMPLES_ROOT"
+
+ pushd ./Arduino/sketches
+ chmod +x ./compile-all-examples.sh
+
+ # The script expects all the examples to be in the current directory.
+ # So copy from local directory to newly instlled wolfssl arduino library to compile there.
+ cp ./compile-all-examples.sh "$ARDUINO_ROOT/wolfssl/examples/compile-all-examples.sh"
+ cp ./board_list.txt "$ARDUINO_ROOT/wolfssl/examples/board_list.txt"
+
+ # Compile the Arduino library examples in-place
+ pushd "$ARDUINO_ROOT/wolfssl/examples/"
+ echo "PWD=$PWD"
+ ./compile-all-examples.sh ./board_list.txt
+ popd
+ popd
- - name: Upload Compilation Artifacts
- uses: actions/upload-artifact@v4
- with:
- name: compiled-sketch
- path: Arduino/sketches/template/build/*
+ # End Compile Arduino Sketches for Various Boards
diff --git a/.gitignore b/.gitignore
index 863d4bde..1ff16e0a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -375,3 +375,6 @@ tpm/evp_tpm
/Arduino/**/Output/*
/Arduino/**/TraceReports/*
/Arduino/**/.visualgdb/*
+/Arduino/sketches/output.log
+/**/*.bak
+
diff --git a/Arduino/README.md b/Arduino/README.md
index efcfca77..6b5be0d5 100644
--- a/Arduino/README.md
+++ b/Arduino/README.md
@@ -14,6 +14,8 @@ Functional examples:
- [sketches/wolfssl_AES_CTR](./sketches/wolfssl_AES_CTR/README.md) AES CTR Encrypt / decrypt.
- [sketches/wolfssl_client](./sketches/wolfssl_client/README.md) TLS Client.
- [sketches/wolfssl_server](./sketches/wolfssl_server/README.md) TLS Server.
+- [sketches/wolfssl_client_dtls](./sketches/wolfssl_client_dtls/README.md) DTLS Client.
+- [sketches/wolfssl_server_dtls](./sketches/wolfssl_server_dtls/README.md) DTLS Server.
Both the `template` and `wolfssl_AES_CTR` examples include VisualGDB project files.
@@ -51,6 +53,34 @@ from [stm32duino/Arduino_Core_STM32](https://github.com/stm32duino/Arduino_Core_
https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json
```
+or
+
+```
+https://raw.githubusercontent.com/stm32duino/BoardManagerFiles/main/package_stmicroelectronics_index.json
+```
+
+ESP8266 Support uses this:
+
+```
+http://arduino.esp8266.com/stable/package_esp8266com_index.json
+```
+
+STM32Duino:
+
+```
+http://dan.drown.org/stm32duino/package_STM32duino_index.json,
+```
+
+Teensy:
+```
+https://www.pjrc.com/teensy/package_teensy_index.json
+```
+
+There are Arduino-specific, compile-time (macros & includes) of interest for these files:
+
+- [settings.h]()
+- [settings.h]()
+
## Using wolfSSL from the Arduino IDE
The Official wolfSSL: https://github.com/wolfSSL/arduino-wolfSSL See [PR #1](https://github.com/wolfSSL/Arduino-wolfSSL/pull/1).
@@ -226,3 +256,9 @@ Build and run `testwolfcrypt`.
./configure --enable-all
make clean && make && ./wolfcrypt/test/testwolfcrypt
```
+
+### Testing
+
+See the enclose [board_list.txt](./board_list.txt) file: a list of fully qualified board names
+that is used by the [github/workflows/arduino.yml](/github/workflows/arduino.yml) action.
+
diff --git a/Arduino/sketches/README.md b/Arduino/sketches/README.md
index 5fc0004e..7278ec72 100644
--- a/Arduino/sketches/README.md
+++ b/Arduino/sketches/README.md
@@ -6,14 +6,32 @@ There are currently five example Arduino sketches:
* [wolfssl_AES_CTR](./wolfssl_AES_CTR/README.md): Basic AES CTR Encryption / Decryption example.
* [wolfssl_client](./wolfssl_client/README.md): Basic TLS listening client.
* [wolfssl_server](./wolfssl_server/README.md): Basic TLS server.
+* [wolfssl_client_dtls](./wolfssl_client_dtls/README.md): Basic DTLS listening client.
+* [wolfssl_server_dtls](./wolfssl_server_dtls/README.md): Basic DTLS server.
* [wolfssl_version](./wolfssl_version/README.md): Bare-bones wolfSSL example.
Examples have been most recently confirmed operational on the
-[Arduino IDE](https://www.arduino.cc/en/software) 2.2.1.
+[Arduino IDE](https://www.arduino.cc/en/software) 2.3.6.
For examples on other platforms, see the [IDE directory](https://github.com/wolfssl/wolfssl/tree/master/IDE).
Additional wolfssl examples can be found at [wolfSSL/wolfssl-examples](https://github.com/wolfSSL/wolfssl-examples/).
+## Testing
+
+See GitHub workflow files:
+
+- [wolfssl/arduino.yml](https://github.com/wolfssl/wolfssl/blob/master/.github/workflows/arduino.yml) Arduino CI Build (1 of 4) wolfssl
+- [wolfssl-examples/arduino-release.yml](https://github.com/wolfssl/wolfssl-examples/blob/master/.github/workflows/arduino-release.yml) Arduino CI Build (2 of 4) Release Arduino wolfSSL for Local Examples
+- [wolfssl-examples/arduino.yml](https://github.com/wolfssl/wolfssl-examples/blob/master/.github/workflows/arduino.yml) Arduino CI Build (3 of 4) Latest wolfSSL for Local Examples
+- [Arduino-wolfSSL](https://github.com/wolfssl/Arduino-wolfSSL/blob/master/.github/workflows/arduino.yml) Arduino CI Build (4 of 4) Arduino-wolfSSL
+
+Note that the local files here are copied to other repositories as needed from the workflow jobs:
+
+- `arduino_install.sh` Local copy of https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh
+- `board_list.txt` Comprehensive known tested boards, used by GitHub actions in wolfssl, Arduino-wolfssl, and this repo.
+- `board_list_v5.8.2_.txt` Release v5.8.2 known tested boards, used by GitHub actions in wolfssl, Arduino-wolfssl, and this repo.
+- `compile-all-examples.sh` Compile all examples for all sketches in current directory.
+
## Using wolfSSL
The typical include will look something like this:
diff --git a/Arduino/sketches/arduino_install.sh b/Arduino/sketches/arduino_install.sh
new file mode 100644
index 00000000..bd1ff02c
--- /dev/null
+++ b/Arduino/sketches/arduino_install.sh
@@ -0,0 +1,243 @@
+#!/bin/sh
+# Source: https://github.com/arduino/tooling-project-assets/blob/main/other/installation-script/install.sh
+
+# The original version of this script (https://github.com/Masterminds/glide.sh/blob/master/get) is licensed under the
+# MIT license. See https://github.com/Masterminds/glide/blob/master/LICENSE for more details and copyright notice.
+
+# This local copy at wolfSSL was created for GitHub workflow files that occasionally would fail to fetch at run.
+
+PROJECT_OWNER="arduino"
+PROJECT_NAME="arduino-cli"
+
+# BINDIR represents the local bin location, defaults to ./bin.
+EFFECTIVE_BINDIR=""
+DEFAULT_BINDIR="$PWD/bin"
+TEMPDIR="${TMPDIR:-${TEMP:-${TMP:-/tmp}}}"
+
+fail() {
+ echo "$1"
+ exit 1
+}
+
+initDestination() {
+ if [ -n "$BINDIR" ]; then
+ if [ ! -d "$BINDIR" ]; then
+ # The second instance of $BINDIR is intentionally a literal in this message.
+ # shellcheck disable=SC2016
+ fail "$BINDIR "'($BINDIR)'" folder not found. Please create it before continuing."
+ fi
+ EFFECTIVE_BINDIR="$BINDIR"
+ else
+ if [ ! -d "$DEFAULT_BINDIR" ]; then
+ mkdir "$DEFAULT_BINDIR"
+ fi
+ EFFECTIVE_BINDIR="$DEFAULT_BINDIR"
+ fi
+ echo "Installing in $EFFECTIVE_BINDIR"
+}
+
+initArch() {
+ ARCH=$(uname -m)
+ case $ARCH in
+ armv5*) ARCH="armv5" ;;
+ armv6*) ARCH="ARMv6" ;;
+ armv7*) ARCH="ARMv7" ;;
+ aarch64) ARCH="ARM64" ;;
+ arm64) ARCH="ARM64" ;;
+ x86) ARCH="32bit" ;;
+ x86_64) ARCH="64bit" ;;
+ i686) ARCH="32bit" ;;
+ i386) ARCH="32bit" ;;
+ esac
+ echo "ARCH=$ARCH"
+}
+
+initFallbackArch() {
+ case "${OS}_${ARCH}" in
+ macOS_ARM64)
+ # Rosetta 2 allows applications built for x86-64 hosts to run on the ARM 64-bit M1 processor
+ FALLBACK_ARCH='64bit'
+ ;;
+ esac
+}
+
+initOS() {
+ OS=$(uname -s)
+ case "$OS" in
+ Linux*) OS='Linux' ;;
+ Darwin*) OS='macOS' ;;
+ MINGW*) OS='Windows' ;;
+ MSYS*) OS='Windows' ;;
+ esac
+ echo "OS=$OS"
+}
+
+initDownloadTool() {
+ if command -v "curl" >/dev/null 2>&1; then
+ DOWNLOAD_TOOL="curl"
+ elif command -v "wget" >/dev/null 2>&1; then
+ DOWNLOAD_TOOL="wget"
+ else
+ fail "You need curl or wget as download tool. Please install it first before continuing"
+ fi
+ echo "Using $DOWNLOAD_TOOL as download tool"
+}
+
+# checkLatestVersion() sets the CHECKLATESTVERSION_TAG variable to the latest version
+checkLatestVersion() {
+ # Use the GitHub releases webpage to find the latest version for this project
+ # so we don't get rate-limited.
+ CHECKLATESTVERSION_REGEX="v\?[0-9][A-Za-z0-9\.-]*"
+ CHECKLATESTVERSION_LATEST_URL="https://github.com/${PROJECT_OWNER}/${PROJECT_NAME}/releases/latest"
+ if [ "$DOWNLOAD_TOOL" = "curl" ]; then
+ CHECKLATESTVERSION_TAG=$(curl -SsL $CHECKLATESTVERSION_LATEST_URL | grep -o "
Release $CHECKLATESTVERSION_REGEX · ${PROJECT_OWNER}/${PROJECT_NAME}" | grep -o "$CHECKLATESTVERSION_REGEX")
+ elif [ "$DOWNLOAD_TOOL" = "wget" ]; then
+ CHECKLATESTVERSION_TAG=$(wget -q -O - $CHECKLATESTVERSION_LATEST_URL | grep -o "Release $CHECKLATESTVERSION_REGEX · ${PROJECT_OWNER}/${PROJECT_NAME}" | grep -o "$CHECKLATESTVERSION_REGEX")
+ fi
+ if [ "$CHECKLATESTVERSION_TAG" = "" ]; then
+ echo "Cannot determine latest tag."
+ exit 1
+ fi
+}
+
+getFile() {
+ GETFILE_URL="$1"
+ GETFILE_FILE_PATH="$2"
+ if [ "$DOWNLOAD_TOOL" = "curl" ]; then
+ GETFILE_HTTP_STATUS_CODE=$(curl --silent --show-error --write-out '%{http_code}' --location "$GETFILE_URL" -o "$GETFILE_FILE_PATH")
+ elif [ "$DOWNLOAD_TOOL" = "wget" ]; then
+ TMP_FILE=$(mktemp)
+ wget --server-response --content-on-error -q -O "$GETFILE_FILE_PATH" "$GETFILE_URL" 2>"$TMP_FILE"
+ GETFILE_HTTP_STATUS_CODE=$(awk '/^ HTTP/{print $2}' "$TMP_FILE")
+ rm -f "$TMP_FILE"
+ fi
+ echo "$GETFILE_HTTP_STATUS_CODE"
+}
+
+downloadFile() {
+ if [ -z "$1" ]; then
+ checkLatestVersion
+ TAG="$CHECKLATESTVERSION_TAG"
+ else
+ TAG=$1
+ fi
+ # arduino-lint_0.4.0-rc1_Linux_64bit.[tar.gz, zip]
+ APPLICATION_DIST_PREFIX="${PROJECT_NAME}_${TAG#"v"}_"
+ if [ "$OS" = "Windows" ]; then
+ APPLICATION_DIST_EXTENSION=".zip"
+ else
+ APPLICATION_DIST_EXTENSION=".tar.gz"
+ fi
+ APPLICATION_DIST="${APPLICATION_DIST_PREFIX}${OS}_${ARCH}${APPLICATION_DIST_EXTENSION}"
+
+ # Support specifying nightly build versions (e.g., "nightly-latest") via the script argument.
+ case "$TAG" in
+ nightly*)
+ DOWNLOAD_URL_PREFIX="https://downloads.arduino.cc/${PROJECT_NAME}/nightly/"
+ ;;
+ *)
+ DOWNLOAD_URL_PREFIX="https://downloads.arduino.cc/${PROJECT_NAME}/"
+ ;;
+ esac
+ DOWNLOAD_URL="${DOWNLOAD_URL_PREFIX}${APPLICATION_DIST}"
+
+ INSTALLATION_TMP_FILE="${TEMPDIR}/$APPLICATION_DIST"
+ echo "Downloading $DOWNLOAD_URL"
+ httpStatusCode=$(getFile "$DOWNLOAD_URL" "$INSTALLATION_TMP_FILE")
+ if [ "$httpStatusCode" -ne 200 ]; then
+ if [ -n "$FALLBACK_ARCH" ]; then
+ echo "$OS $ARCH release not currently available. Checking for alternative $OS $FALLBACK_ARCH release for your system."
+ FALLBACK_APPLICATION_DIST="${APPLICATION_DIST_PREFIX}${OS}_${FALLBACK_ARCH}${APPLICATION_DIST_EXTENSION}"
+ DOWNLOAD_URL="${DOWNLOAD_URL_PREFIX}${FALLBACK_APPLICATION_DIST}"
+ echo "Downloading $DOWNLOAD_URL"
+ httpStatusCode=$(getFile "$DOWNLOAD_URL" "$INSTALLATION_TMP_FILE")
+ fi
+
+ if [ "$httpStatusCode" -ne 200 ]; then
+ echo "Did not find a release for your system: $OS $ARCH"
+ echo "Trying to find a release using the GitHub API."
+
+ LATEST_RELEASE_URL="https://api.github.com/repos/${PROJECT_OWNER}/$PROJECT_NAME/releases/tags/$TAG"
+ TMP_BODY_FILE=$(mktemp)
+ HTTP_STATUS_CODE=$(getFile "$LATEST_RELEASE_URL" "$TMP_BODY_FILE")
+ BODY=$(cat "$TMP_BODY_FILE")
+ rm -f "$TMP_BODY_FILE"
+ if [ "$HTTP_STATUS_CODE" != 200 ]; then
+ echo "Request failed with HTTP status code $HTTP_STATUS_CODE"
+ fail "Body: $BODY"
+ fi
+
+ # || true forces this command to not catch error if grep does not find anything
+ DOWNLOAD_URL=$(echo "$BODY" | grep 'browser_' | cut -d\" -f4 | grep "$APPLICATION_DIST") || true
+ if [ -z "$DOWNLOAD_URL" ]; then
+ DOWNLOAD_URL=$(echo "$BODY" | grep 'browser_' | cut -d\" -f4 | grep "$FALLBACK_APPLICATION_DIST") || true
+ fi
+
+ if [ -z "$DOWNLOAD_URL" ]; then
+ echo "Sorry, we dont have a dist for your system: $OS $ARCH"
+ fail "You can request one here: https://github.com/${PROJECT_OWNER}/$PROJECT_NAME/issues"
+ else
+ echo "Downloading $DOWNLOAD_URL"
+ getFile "$DOWNLOAD_URL" "$INSTALLATION_TMP_FILE"
+ fi
+ fi
+ fi
+}
+
+installFile() {
+ INSTALLATION_TMP_DIR="${TEMPDIR}/$PROJECT_NAME"
+ mkdir -p "$INSTALLATION_TMP_DIR"
+ if [ "$OS" = "Windows" ]; then
+ unzip -d "$INSTALLATION_TMP_DIR" "$INSTALLATION_TMP_FILE"
+ else
+ tar xf "$INSTALLATION_TMP_FILE" -C "$INSTALLATION_TMP_DIR"
+ fi
+ INSTALLATION_TMP_BIN="$INSTALLATION_TMP_DIR/$PROJECT_NAME"
+ cp "$INSTALLATION_TMP_BIN" "$EFFECTIVE_BINDIR"
+ rm -rf "$INSTALLATION_TMP_DIR"
+ rm -f "$INSTALLATION_TMP_FILE"
+}
+
+bye() {
+ BYE_RESULT=$?
+ if [ "$BYE_RESULT" != "0" ]; then
+ echo "Failed to install $PROJECT_NAME"
+ fi
+ exit $BYE_RESULT
+}
+
+testVersion() {
+ set +e
+ if EXECUTABLE_PATH="$(command -v $PROJECT_NAME)"; then
+ # Convert to resolved, absolute paths before comparison
+ EXECUTABLE_REALPATH="$(cd -- "$(dirname -- "$EXECUTABLE_PATH")" && pwd -P)"
+ EFFECTIVE_BINDIR_REALPATH="$(cd -- "$EFFECTIVE_BINDIR" && pwd -P)"
+ if [ "$EXECUTABLE_REALPATH" != "$EFFECTIVE_BINDIR_REALPATH" ]; then
+ # $PATH is intentionally a literal in this message.
+ # shellcheck disable=SC2016
+ echo "An existing $PROJECT_NAME was found at $EXECUTABLE_PATH. Please prepend \"$EFFECTIVE_BINDIR\" to your "'$PATH'" or remove the existing one."
+ fi
+ else
+ # $PATH is intentionally a literal in this message.
+ # shellcheck disable=SC2016
+ echo "install.sh: $PROJECT_NAME not found. You might want to add \"$EFFECTIVE_BINDIR\" to your "'$PATH'
+ fi
+
+ set -e
+ APPLICATION_VERSION="$("$EFFECTIVE_BINDIR/$PROJECT_NAME" version)"
+ echo "$APPLICATION_VERSION installed successfully in $EFFECTIVE_BINDIR"
+}
+
+# Execution
+
+#Stop execution on any error
+trap "bye" EXIT
+initDestination
+set -e
+initArch
+initOS
+initFallbackArch
+initDownloadTool
+downloadFile "$1"
+installFile
+testVersion
diff --git a/Arduino/sketches/board_list.txt b/Arduino/sketches/board_list.txt
new file mode 100644
index 00000000..52c78b41
--- /dev/null
+++ b/Arduino/sketches/board_list.txt
@@ -0,0 +1,173 @@
+# Edit with caution.
+#
+# This is a list of Arduino fqbn (fully qualified board names).
+#
+# Syntax:
+#
+# fqbn # fully qualified Arduino board name in format x:y:z, with optional comment after "#"
+# --no-[example] # to optionally exclude an example. This comment displayed as for reason
+#
+# Each line is the exact text used in the ./compile-all-examples.sh
+#
+# See also:
+# [this repo wolfssl-examples]/.github/workflows/arduino.yml
+# [this repo wolfssl-examples]/.github/workflows/arduino-release.yml
+# [other repo wolfssl]/.github/workflows/arduino.yml
+# [other repo Arduino-wolfssl]/.github/workflows/arduino.yml
+#
+# This exact boardlist.txt is also used by:
+# [repo owner]/Arduino-wolfSSL/.github/workflows/arduino.yml
+# [repo owner]/wolfssl/.github/workflows/arduino.yml
+#
+# There's only one reference `board_list.txt` (this file)
+# - copied to other workflows as needed with curl.
+#
+# There's only one compiling script `compile-all-examples.sh` (in this directory)
+# - copied to other workflows as needed with curl.
+#
+# To view available boards:
+# arduino-cli board listall | grep '^esp32:esp32:'
+#
+
+arduino:avr:leonardoeth
+ # Ethernet Leonardo ETH (ATmega32u4 + W5500 Ethernet), only 2K RAM
+ --no-wolfssl_AES_CTR # Global variables use 4973 bytes (194%) of dynamic memory, leaving -2413 bytes for local variables. Maximum is 2560 bytes.
+ --no-wolfssl_client # Global variables use 4973 bytes (194%) of dynamic memory, leaving -2413 bytes for local variables. Maximum is 2560 bytes.
+ --no-wolfssl_server # Global variables use 4973 bytes (194%) of dynamic memory, leaving -2413 bytes for local variables. Maximum is 2560 bytes.
+ --no-wolfssl_client_dtls # Global variables use 4973 bytes (194%) of dynamic memory, leaving -2413 bytes for local variables. Maximum is 2560 bytes.
+ --no-wolfssl_server_dtls # Global variables use 4973 bytes (194%) of dynamic memory, leaving -2413 bytes for local variables. Maximum is 2560 bytes.
+
+
+arduino:avr:yun
+ # Ethernet & WiFi has AR9331 Linux module for networking, but only 2K RAM
+ --no-wolfssl_AES_CTR # Global variables use 4973 bytes (194%) of dynamic memory, leaving -2413 bytes for local variables. Maximum is 2560 bytes.
+ --no-wolfssl_client # Global variables use 4973 bytes (194%) of dynamic memory, leaving -2413 bytes for local variables. Maximum is 2560 bytes.
+ --no-wolfssl_server # Global variables use 4973 bytes (194%) of dynamic memory, leaving -2413 bytes for local variables. Maximum is 2560 bytes.
+ --no-wolfssl_client_dtls # Global variables use 4973 bytes (194%) of dynamic memory, leaving -2413 bytes for local variables. Maximum is 2560 bytes.
+ --no-wolfssl_server_dtls # Global variables use 4973 bytes (194%) of dynamic memory, leaving -2413 bytes for local variables. Maximum is 2560 bytes.
+
+arduino:samd:mkrwifi1010
+ # WiFi NINA-W102 module
+ --no-wolfssl_client_dtls # TODO This example requires WOLFSSL_DTLS. See user_settings.h in the Arduino wolfssl library
+ --no-wolfssl_server_dtls # TODO This example requires WOLFSSL_DTLS. See user_settings.h in the Arduino wolfssl library
+
+arduino:samd:mkr1000
+ # WiFi uses WINC1500 module
+ --no-template # TODO wolfio.h:290:32: error: 'EWOULDBLOCK' undeclared (first use in this function); did you mean 'MP_WOULDBLOCK'?
+ --no-wolfssl_AES_CTR # TODO wolfio.h:290:32: error: 'EWOULDBLOCK' undeclared (first use in this function); did you mean 'MP_WOULDBLOCK'?
+ --no-wolfssl_client # TODO wolfio.h:290:32: error: 'EWOULDBLOCK' undeclared (first use in this function); did you mean 'MP_WOULDBLOCK'?
+ --no-wolfssl_server # TODO wolfio.h:290:32: error: 'EWOULDBLOCK' undeclared (first use in this function); did you mean 'MP_WOULDBLOCK'?
+ --no-wolfssl_client_dtls # TODO wolfio.h:290:32: error: 'EWOULDBLOCK' undeclared (first use in this function); did you mean 'MP_WOULDBLOCK'?
+ --no-wolfssl_server_dtls # TODO wolfio.h:290:32: error: 'EWOULDBLOCK' undeclared (first use in this function); did you mean 'MP_WOULDBLOCK'?
+ --no-wolfssl_version # TODO wolfio.h:290:32: error: 'EWOULDBLOCK' undeclared (first use in this function); did you mean 'MP_WOULDBLOCK'?
+
+arduino:samd:mkrfox1200
+ # Sigfox Low-power IoT radio
+ --no-wolfssl_client # TODO WiFiNINA/src/utility/spi_drv.cpp:103:15: error: 'NINA_GPIO0' was not declared in this scope
+ --no-wolfssl_server # TODO WiFiNINA/src/utility/spi_drv.cpp:103:15: error: 'NINA_GPIO0' was not declared in this scope
+ --no-wolfssl_client_dtls # TODO WiFiNINA/src/utility/spi_drv.cpp:103:15: error: 'NINA_GPIO0' was not declared in this scope
+ --no-wolfssl_server_dtls # TODO WiFiNINA/src/utility/spi_drv.cpp:103:15: error: 'NINA_GPIO0' was not declared in this scope
+
+arduino:mbed_nano:nanorp2040connect
+ # WiFi NINA-W102 module
+ --no-wolfssl_client_dtls # TODO This example requires WOLFSSL_DTLS. See user_settings.h in the Arduino wolfssl library
+ --no-wolfssl_server_dtls # TODO This example requires WOLFSSL_DTLS. See user_settings.h in the Arduino wolfssl library
+
+# The like (ABX00045) and regular (ABX00042) are considered equivalent
+# The Portenta devices are Linux-like and not typical Arduino boards
+arduino:mbed_portenta:envie_m7
+ # WiFi & Ethernet via onboard module
+ --no-wolfssl_client_dtls # TODO This example requires WOLFSSL_DTLS. See user_settings.h in the Arduino wolfssl library
+ --no-wolfssl_server_dtls # TODO This example requires WOLFSSL_DTLS. See user_settings.h in the Arduino wolfssl library
+
+# The Portenta devices are Linux-like and not typical Arduino boards
+arduino:mbed_portenta:portenta_x8
+ # WiFi & Ethernet via onboard module
+ --no-wolfssl_client # TODO mbed_portenta/4.4.1/libraries/WiFi/src/WiFi.h:188:3: error: 'WiFiAccessPoint' does not name a type
+ --no-wolfssl_server # TODO mbed_portenta/4.4.1/libraries/WiFi/src/WiFi.h:188:3: error: 'WiFiAccessPoint' does not name a type
+ --no-wolfssl_client_dtls # TODO This example requires WOLFSSL_DTLS. See user_settings.h in the Arduino wolfssl library
+ --no-wolfssl_server_dtls # TODO This example requires WOLFSSL_DTLS. See user_settings.h in the Arduino wolfssl library
+
+arduino:mbed_edge:edge_control
+ # Cellular LTE Cat-M/NB-IoT
+ --no-wolfssl_client # TODO Wrong network? WiFiNINA/src/utility/spi_drv.cpp:103:15: error: 'NINA_GPIO0' was not declared in this scope
+ --no-wolfssl_server # TODO Wrong network? WiFiNINA/src/utility/spi_drv.cpp:103:15: error: 'NINA_GPIO0' was not declared in this scope
+ --no-wolfssl_client # TODO Wrong network? WiFiNINA/src/utility/spi_drv.cpp:103:15: error: 'NINA_GPIO0' was not declared in this scope
+ --no-wolfssl_server # TODO Wrong network? WiFiNINA/src/utility/spi_drv.cpp:103:15: error: 'NINA_GPIO0' was not declared in this scope
+ --no-wolfssl_client_dtls # TODO This example requires WOLFSSL_DTLS. See user_settings.h in the Arduino wolfssl library
+ --no-wolfssl_server_dtls # TODO This example requires WOLFSSL_DTLS. See user_settings.h in the Arduino wolfssl library
+
+arduino:renesas_uno:unor4wifi
+ # WiFi & BT UNO R4 WiFi (ESP32-S3 coprocessor)
+ --no-wolfssl_client_dtls # TODO This example requires WOLFSSL_DTLS. See user_settings.h in the Arduino wolfssl library
+ --no-wolfssl_server_dtls # TODO This example requires WOLFSSL_DTLS. See user_settings.h in the Arduino wolfssl library
+
+arduino:avr:mega
+ --no-wolfssl_client # There's no wifi on mega for client example
+ --no-wolfssl_server # There's no wifi on mega for server example
+ --no-wolfssl_client_dtls # There's no wifi on mega for client DTLS example
+ --no-wolfssl_server_dtls # There's no wifi on mega for server DTLS example
+arduino:avr:nano
+ --no-wolfssl_AES_CTR # Global variables use 5010 bytes (244%) of dynamic memory, leaving -2962 bytes for local variables. Maximum is 2048 bytes.
+ --no-wolfssl_client # There's no wifi on nano for client example
+ --no-wolfssl_server # There's no wifi on nano for server example
+ --no-wolfssl_client_dtls # There's no wifi on nano for client DTLS example
+ --no-wolfssl_server_dtls # There's no wifi on nano for server DTLS example
+arduino:avr:uno
+ --no-wolfssl_AES_CTR # Global variables use 5010 bytes (244%) of dynamic memory, leaving -2962 bytes for local variables. Maximum is 2048 bytes.
+ --no-wolfssl_client # There's no wifi on uno for client example
+ --no-wolfssl_server # There's no wifi on uno for server example
+ --no-wolfssl_client_dtls # There's no wifi on uno for client DTLS example
+ --no-wolfssl_server_dtls # There's no wifi on uno for server DTLS example
+
+# Although it may have network capability, flash is pretty small:
+arduino:avr:ethernet
+ --no-wolfssl_AES_CTR # Global variables use 5010 bytes (244%) of dynamic memory, leaving -2962 bytes for local variables. Maximum is 2048 bytes.
+ --no-wolfssl_client # Global variables use 5010 bytes (244%) of dynamic memory, leaving -2962 bytes for local variables. Maximum is 2048 bytes.
+ --no-wolfssl_server # Global variables use 5010 bytes (244%) of dynamic memory, leaving -2962 bytes for local variables. Maximum is 2048 bytes.
+ --no-wolfssl_client_dtls # Global variables use 5010 bytes (244%) of dynamic memory, leaving -2962 bytes for local variables. Maximum is 2048 bytes.
+ --no-wolfssl_server_dtls # Global variables use 5010 bytes (244%) of dynamic memory, leaving -2962 bytes for local variables. Maximum is 2048 bytes.
+
+arduino:sam:arduino_due_x
+ --no-wolfssl_client_dtls # TODO This example requires WOLFSSL_DTLS. See user_settings.h in the Arduino wolfssl library
+ --no-wolfssl_server_dtls # TODO This example requires WOLFSSL_DTLS. See user_settings.h in the Arduino wolfssl library
+
+arduino:samd:arduino_zero_native
+ --no-wolfssl_client # TODO error: 'NINA_GPIO0' was not declared in this scope
+ --no-wolfssl_server # TODO error: 'NINA_GPIO0' was not declared in this scope
+ --no-wolfssl_client_dtls # TODO error: 'NINA_GPIO0' was not declared in this scope
+ --no-wolfssl_server_dtls # TODO error: 'NINA_GPIO0' was not declared in this scope
+
+
+# Pseudo network via bridge.h only. No connect / write / etc.
+arduino:samd:tian
+ --no-wolfssl_client # HttpClient cannot be used for this example
+ --no-wolfssl_server # HttpClient cannot be used for this example
+ --no-wolfssl_client_dtls # HttpClient cannot be used for this example
+ --no-wolfssl_server_dtls # HttpClient cannot be used for this example
+
+# All examples should work on (nearly all) ESP32 devices
+esp32:esp32:esp32
+esp32:esp32:esp32s2
+esp32:esp32:esp32s3
+esp32:esp32:esp32c3
+esp32:esp32:esp32c6
+
+# Except for the ESP32-H2 what does not have WiFi
+esp32:esp32:esp32h2
+ --no-wolfssl_client # There's no WiFi on esp32h2 for client example
+ --no-wolfssl_server # There's no WiFi on esp32h2 for server example
+ --no-wolfssl_client_dtls # There's no WiFi on esp32h2 for client DTLS example
+ --no-wolfssl_server_dtls # There's no WiFi on esp32h2 for server DTLS example
+
+esp8266:esp8266:generic
+ --no-wolfssl_client # There's not enough memory on ESP8266 at this time (TODO)
+ --no-wolfssl_server # There's not enough memory on ESP8266 at this time (TODO)
+ --no-wolfssl_client_dtls # There's not enough memory on ESP8266 at this time (TODO)
+ --no-wolfssl_server_dtls # There's not enough memory on ESP8266 at this time (TODO)
+
+teensy:avr:teensy40
+ --no-wolfssl_client # TODO: Wrong network? WiFiNINA/src/utility/wifi_drv.h:300:12: error: 'PinStatus' does not name a type
+ --no-wolfssl_server # TODO: Wrong network? WiFiNINA/src/utility/wifi_drv.h:300:12: error: 'PinStatus' does not name a type
+ --no-wolfssl_client_dtls # TODO: This example requires WOLFSSL_DTLS. See user_settings.h in the Arduino wolfssl library
+ --no-wolfssl_server_dtls # TODO: This example requires WOLFSSL_DTLS. See user_settings.h in the Arduino wolfssl library
diff --git a/Arduino/sketches/board_list_v5.8.2.txt b/Arduino/sketches/board_list_v5.8.2.txt
new file mode 100644
index 00000000..f811e3ce
--- /dev/null
+++ b/Arduino/sketches/board_list_v5.8.2.txt
@@ -0,0 +1,123 @@
+# Edit with caution.
+#
+# TODO this is an interim board list file for current release of Arduino wolfSSL
+#
+# See ./board_list for more comprehensive list of boards.
+#
+# This is a list of Arduino fqbn (fully qualified board names).
+#
+# Syntax:
+#
+# fqbn # fully qualified Arduino board name in format x:y:z, with optional comment after "#"
+# --no-[example] # to optionally exclude an example. This comment displayed as for reason
+#
+# Each line is the exact text used in the ./compile-all-examples.sh
+#
+# See also:
+# [this repo wolfssl-examples]/.github/workflows/arduino.yml
+# [this repo wolfssl-examples]/.github/workflows/arduino-release.yml
+# [other repo wolfssl]/.github/workflows/arduino.yml
+# [other repo Arduino-wolfssl]/.github/workflows/arduino.yml
+#
+# This exact boardlist.txt is also used by:
+# [repo owner]/Arduino-wolfSSL/.github/workflows/arduino.yml
+# [repo owner]/wolfssl/.github/workflows/arduino.yml
+#
+# There's only one reference `board_list.txt` (this file)
+# - copied to other workflows as needed with curl.
+#
+# There's only one compiling script `compile-all-examples.sh` (in this directory)
+# - copied to other workflows as needed with curl.
+#
+# To view available boards:
+# arduino-cli board listall | grep '^esp32:esp32:'
+#
+
+arduino:avr:mega
+ --no-wolfssl_version # Fixed in https://github.com/wolfSSL/wolfssl/pull/9075 Force old OID values: WOLFSSL_OLD_OID_SUM for WC_16BIT_CPU
+ --no-template # Fixed in https://github.com/wolfSSL/wolfssl/pull/9075 Force old OID values: WOLFSSL_OLD_OID_SUM for WC_16BIT_CPU
+ --no-wolfssl_AES_CTR # Fixed in https://github.com/wolfSSL/wolfssl/pull/9075 Force old OID values: WOLFSSL_OLD_OID_SUM for WC_16BIT_CPU
+ --no-wolfssl_client # there's no wifi on mega for client examplex
+ --no-wolfssl_server # there's no wifi on mega for server example
+ --no-wolfssl_client_dtls # there's no wolfssl_client_dtls example for the v5.8.2 release
+ --no-wolfssl_server_dtls # there's no wolfssl_server_dtls example for the v5.8.2 release
+
+arduino:avr:nano
+ --no-wolfssl_version # Fixed in https://github.com/wolfSSL/wolfssl/pull/9075 Force old OID values: WOLFSSL_OLD_OID_SUM for WC_16BIT_CPU
+ --no-template # Fixed in https://github.com/wolfSSL/wolfssl/pull/9075 Force old OID values: WOLFSSL_OLD_OID_SUM for WC_16BIT_CPU
+ --no-wolfssl_AES_CTR # Fixed in https://github.com/wolfSSL/wolfssl/pull/9075 Force old OID values: WOLFSSL_OLD_OID_SUM for WC_16BIT_CPU
+ --no-wolfssl_AES_CTR # Global variables use 5010 bytes (244%) of dynamic memory, leaving -2962 bytes for local variables. Maximum is 2048 bytes.
+ --no-wolfssl_client # there's no wifi on nano for client example
+ --no-wolfssl_server # there's no wifi on nano for server example
+ --no-wolfssl_client_dtls # there's no wolfssl_client_dtls example for the v5.8.2 release
+ --no-wolfssl_server_dtls # there's no wolfssl_server_dtls example for the v5.8.2 release
+
+arduino:avr:uno
+ --no-wolfssl_version # Fixed in https://github.com/wolfSSL/wolfssl/pull/9075 Force old OID values: WOLFSSL_OLD_OID_SUM for WC_16BIT_CPU
+ --no-template # Fixed in https://github.com/wolfSSL/wolfssl/pull/9075 Force old OID values: WOLFSSL_OLD_OID_SUM for WC_16BIT_CPU
+ --no-wolfssl_AES_CTR # Fixed in https://github.com/wolfSSL/wolfssl/pull/9075 Force old OID values: WOLFSSL_OLD_OID_SUM for WC_16BIT_CPU
+ --no-wolfssl_AES_CTR # Global variables use 5010 bytes (244%) of dynamic memory, leaving -2962 bytes for local variables. Maximum is 2048 bytes.
+ --no-wolfssl_client # there's no wifi on uno for client example
+ --no-wolfssl_server # there's no wifi on uno for server example
+ --no-wolfssl_client_dtls # there's no wolfssl_client_dtls example for the v5.8.2 release
+ --no-wolfssl_server_dtls # there's no wolfssl_server_dtls example for the v5.8.2 release
+
+# Although it may have network capability, flash is pretty small:
+arduino:avr:ethernet
+ --no-wolfssl_version # Fixed in https://github.com/wolfSSL/wolfssl/pull/9075 Force old OID values: WOLFSSL_OLD_OID_SUM for WC_16BIT_CPU
+ --no-template # Fixed in https://github.com/wolfSSL/wolfssl/pull/9075 Force old OID values: WOLFSSL_OLD_OID_SUM for WC_16BIT_CPU
+ --no-wolfssl_AES_CTR # Global variables use 5010 bytes (244%) of dynamic memory, leaving -2962 bytes for local variables. Maximum is 2048 bytes.
+ --no-wolfssl_client # Global variables use 5010 bytes (244%) of dynamic memory, leaving -2962 bytes for local variables. Maximum is 2048 bytes.
+ --no-wolfssl_server # Global variables use 5010 bytes (244%) of dynamic memory, leaving -2962 bytes for local variables. Maximum is 2048 bytes.
+ --no-wolfssl_client_dtls # there's no wolfssl_client_dtls example for the v5.8.2 release
+ --no-wolfssl_server_dtls # there's no wolfssl_server_dtls example for the v5.8.2 release
+
+arduino:sam:arduino_due_x
+ --no-wolfssl_AES_CTR # Fixed in https://github.com/wolfSSL/wolfssl/pull/9076 Disallow atomics during fence & WOLFSSL_NO_ATOMIC
+ --no-wolfssl_version # Fixed in https://github.com/wolfSSL/wolfssl/pull/9076 Disallow atomics during fence & WOLFSSL_NO_ATOMIC
+ --no-template # Fixed in https://github.com/wolfSSL/wolfssl/pull/9076 Disallow atomics during fence & WOLFSSL_NO_ATOMIC
+ --no-wolfssl_client # Fixed in https://github.com/wolfSSL/wolfssl/pull/9076 Disallow atomics during fence & WOLFSSL_NO_ATOMIC
+ --no-wolfssl_server # Fixed in https://github.com/wolfSSL/wolfssl/pull/9076 Disallow atomics during fence & WOLFSSL_NO_ATOMIC
+ --no-wolfssl_client_dtls # there's no wolfssl_client_dtls example for the v5.8.2 release
+ --no-wolfssl_server_dtls # there's no wolfssl_server_dtls example for the v5.8.2 release
+
+arduino:samd:arduino_zero_native
+ --no-wolfssl_client # TODO error: 'NINA_GPIO0' was not declared in this scope
+ --no-wolfssl_server # TODO error: 'NINA_GPIO0' was not declared in this scope
+ --no-wolfssl_client_dtls # there's no wolfssl_client_dtls example for the v5.8.2 release
+ --no-wolfssl_server_dtls # there's no wolfssl_server_dtls example for the v5.8.2 release
+
+
+# Pseudo network via bridge.h only. No connect / write / etc.
+arduino:samd:tian
+ --no-wolfssl_client # HttpClient cannot be used for this example
+ --no-wolfssl_server # HttpClient cannot be used for this example
+ --no-wolfssl_client_dtls # there's no wolfssl_client_dtls example for the v5.8.2 release
+ --no-wolfssl_server_dtls # there's no wolfssl_server_dtls example for the v5.8.2 release
+
+# All examples should work on (nearly all) ESP32 devices
+esp32:esp32:esp32
+esp32:esp32:esp32s2
+esp32:esp32:esp32s3
+esp32:esp32:esp32c3
+esp32:esp32:esp32c6
+esp32:esp32:esp32h2
+ --no-wolfssl_client # there's no WiFi on esp32h2 for client example
+ --no-wolfssl_server # there's no WiFi on esp32h2 for server example
+ --no-wolfssl_client_dtls # there's no wolfssl_client_dtls example for the v5.8.2 release
+ --no-wolfssl_server_dtls # there's no wolfssl_client_dtls example for the v5.8.2 release
+
+esp8266:esp8266:generic
+ --no-wolfssl_AES_CTR # Fixed in upcoming PR
+ --no-wolfssl_version # Fixed in upcoming PR
+ --no-template # Fixed in upcoming PR
+ --no-wolfssl_client # TODO there's not enough memory on ESP8266 at this time
+ --no-wolfssl_server # TODO there's not enough memory on ESP8266 at this time
+ --no-wolfssl_client_dtls # there's no wolfssl_client_dtls example for the v5.8.2 release
+ --no-wolfssl_server_dtls # there's no wolfssl_server_dtls example for the v5.8.2 release
+
+teensy:avr:teensy40
+ --no-wolfssl_client # Wrong network? WiFiNINA/src/utility/wifi_drv.h:300:12: error: 'PinStatus' does not name a type
+ --no-wolfssl_server # Wrong network? WiFiNINA/src/utility/wifi_drv.h:300:12: error: 'PinStatus' does not name a type
+ --no-wolfssl_client_dtls # there's no wolfssl_client_dtls example for the v5.8.2 release
+ --no-wolfssl_server_dtls # there's no wolfssl_server_dtls example for the v5.8.2 release
diff --git a/Arduino/sketches/compile-all-examples.sh b/Arduino/sketches/compile-all-examples.sh
new file mode 100644
index 00000000..72536021
--- /dev/null
+++ b/Arduino/sketches/compile-all-examples.sh
@@ -0,0 +1,472 @@
+#!/bin/bash
+#
+# ./wolfssl-arduino.sh INSTALL
+# export ARDUINO_ROOT=/home/$USER/Arduino/libraries
+#
+# ./wolfssl-arduino.sh INSTALL /mnt/c/Users/gojimmypi/Documents/Arduino/libraries
+
+# Run shell check to ensure this a good script.
+# Specify the executable shell checker you want to use:
+MY_SHELLCHECK="shellcheck"
+
+# Check if the executable is available in the PATH
+if command -v "$MY_SHELLCHECK" >/dev/null 2>&1; then
+ # Run your command here
+ $MY_SHELLCHECK "$0" || exit 1
+else
+ echo "$MY_SHELLCHECK is not installed. Please install it if changes to this script have been made."
+ exit 1
+fi
+
+set +e
+
+# Configuration parameters
+SHOW_DIR_CONTENTS=0
+SHOW_USER_SETTINGS=0
+SHOW_BOARD_LIST=0
+SHOW_EXAMPLE_LIST=0
+
+# need to reassign ARDUINO_ROOT in this run
+ARDUINO_ROOT="$HOME/Arduino/libraries"
+
+# Used for column alignment; e.g. len(wolfssl_client_dtls) + 2
+MAX_FQBN_LEN=21
+
+# default board list is board_list.txt, may be overridden
+BOARD_LIST="./board_list.txt"
+
+# Unicode in a UTF8 file
+ICON_OK=$(printf "\xE2\x9C\x85")
+ICON_WARN=$(printf "\xE2\x9A\xA0")
+ICON_FAIL=$(printf "\xE2\x9D\x8C")
+
+# Check if board list specified.
+if [ $# -gt 0 ]; then
+ # First parameter may be alternate fqbn list
+ if [[ -f "$1" ]]; then
+ BOARD_LIST="$1"
+ echo "Using specified fqbn list file: $BOARD_LIST"
+ else
+ echo "Error: Parameter specified for board list file does not exist: $1"
+ exit 1
+ fi
+fi
+
+# Internal variabled
+BOARD_CT=0
+BOARD_COMPILE_CT=0
+BOARD_SKIP_CT=0
+BOARD_FAIL_CT=0
+EXAMPLE_CT=0
+THIS_FOUND_FLAG=0
+
+# Assume success unless proven otherwise
+SUCCESS="true"
+
+# Same example names, initialized later
+EXAMPLES=(wolfssl_client wolfssl_client_dtls server)
+
+# associative array, where the keys are arbitrary strings
+declare -A DISABLED # per FQBN: DISABLED["example-name"]=1
+declare -A COMMENT # per FQBN: COMMENT["example-name"]="some comment"
+declare -A VALID_EXAMPLES # set of valid example names
+
+# Indexed arrays to hold results
+declare -a SUMMARY_STATUS
+declare -a SUMMARY_BOARD
+declare -a SUMMARY_EXAMPLE
+
+echo "Icon check:"
+printf '--OK: %s; Warn: %s; Not OK: %s\n' "$ICON_OK" "$ICON_WARN" "$ICON_FAIL"
+
+if [[ $SHOW_DIR_CONTENTS -ne 0 ]]; then
+ echo "********************************************************************************"
+ echo "Installed libraries:"
+ echo "********************************************************************************"
+ ls "$ARDUINO_ROOT" -al
+
+ echo "********************************************************************************"
+ echo "wolfssl:"
+ echo "********************************************************************************"
+ ls "$ARDUINO_ROOT/wolfssl" -al
+
+ echo "********************************************************************************"
+ echo "wolfssl/src:"
+ echo "********************************************************************************"
+ ls "$ARDUINO_ROOT/wolfssl/src/" -al
+
+ echo "********************************************************************************"
+ echo "********************************************************************************"
+ ls "$ARDUINO_ROOT/wolfssl/src/user_settings.h" -al
+ echo "********************************************************************************"
+ echo "********************************************************************************"
+fi
+if [[ $SHOW_USER_SETTINGS -ne 0 ]]; then
+ cat "$ARDUINO_ROOT/wolfssl/src/user_settings.h"
+ echo "********************************************************************************"
+ echo "********************************************************************************"
+fi
+if [[ $SHOW_BOARD_LIST -ne 0 ]]; then
+ echo "Begin compile for $BOARD_LIST"
+ cat "$BOARD_LIST"
+ echo "--------------------------------------------------------------------------------"
+fi
+if [[ $SHOW_EXAMPLE_LIST -ne 0 ]]; then
+ echo "Examples found:"
+ find ./ -mindepth 1 -maxdepth 1 -type d
+ echo "********************************************************************************"
+ echo "********************************************************************************"
+fi
+
+
+#FAIL_LIST=() # items like "fqbn example exitcode"
+#OVERALL_OK=1 # flip to 0 on first failure
+
+# -------- helper functions --------
+
+strip_cr() {
+ if [[ $1 == *$'\r' ]]; then
+ printf '%s' "${1%$'\r'}"
+ else
+ printf '%s' "$1"
+ fi
+}
+
+is_skip() {
+ # skip blank lines or lines that start with # (leading spaces allowed)
+ # [[ -z $1 || $1 =~ ^[[:space:]]*# ]]
+ local line="$1"
+ LINE_VALUE=""
+ LINE_COMMENT=""
+
+ # Trim leading/trailing spaces from the whole line
+ line="${line#"${line%%[![:space:]]*}"}" # trim leading
+ line="${line%"${line##*[![:space:]]}"}" # trim trailing
+
+ # Blank line?
+ if [[ -z $line ]]; then
+ # echo "is_skip early return 0"
+ return 0
+ fi
+
+ # Split at first '#'
+ LINE_VALUE="${line%%#*}"
+ LINE_COMMENT=""
+ if [[ $line == *"#"* ]]; then
+ LINE_COMMENT="${line#*#}"
+ fi
+
+ # Trim each part
+ LINE_VALUE="${LINE_VALUE%"${LINE_VALUE##*[![:space:]]}"}"
+ LINE_VALUE="${LINE_VALUE#"${LINE_VALUE%%[![:space:]]*}"}"
+ # echo "LINE_VALUE=$LINE_VALUE"
+
+ LINE_COMMENT="${LINE_COMMENT%"${LINE_COMMENT##*[![:space:]]}"}"
+ LINE_COMMENT="${LINE_COMMENT#"${LINE_COMMENT%%[![:space:]]*}"}"
+ # echo "LINE_COMMENT=$LINE_COMMENT"
+
+ # Pure comment line (no value)
+ if [[ -z $LINE_VALUE ]]; then
+ # echo "is_skip return 0"
+ return 0
+ fi
+
+ # Not a skip line
+ # echo "is_skip return 1"
+ return 1
+} #is_skip
+
+norm_key() {
+ # lowercase only, preserve underscores and dashes
+ printf '%s' "${1,,}"
+} # norm_key
+
+discover_examples() {
+ EXAMPLES=()
+ EXAMPLE_CT=0
+
+ echo "Discovering examples in current directory $(pwd)"
+ # Read NUL-separated paths to handle spaces safely
+ while IFS= read -r -d '' d; do
+ # strip leading "./" so we keep just the dir name
+ local name="${d#./}"
+ EXAMPLES+=("$name")
+ echo "Found example directory: $name"
+ ((EXAMPLE_CT++))
+ done < <(find ./ -mindepth 1 -maxdepth 1 -type d -print0 | sort -z)
+
+ # Optional: filter out hidden dirs or known exclusions
+ # local keep=()
+ # for e in "${EXAMPLES[@]}"; do
+ # [[ $e == .* ]] && continue # skip hidden like .git
+ # [[ $e == build || $e == out ]] && continue
+ # keep+=("$e")
+ # done
+ # EXAMPLES=("${keep[@]}")
+} # discover_examples
+
+build_valid_examples() {
+ local e key
+ for e in "${EXAMPLES[@]}"; do
+ key=$(norm_key "$e")
+ VALID_EXAMPLES["$key"]=1
+ done
+} # build_valid_examples
+
+warn_unknown_flag() {
+ # $1 is raw flag text after --no-
+ # $2 is current FQBN for context
+ printf '%s WARN: Unknown example in flag "--no-%s" under FQBN "%s" (ignored)\n' "$ICON_WARN" "$1" "$2" >&2
+} # warn_unknown_flag
+
+set_flag() {
+ # flag looks like --no-name
+ local raw=${1#--no-}
+ local key
+ key=$(norm_key "$raw")
+ # echo "this key = $key"
+ if [[ -n ${VALID_EXAMPLES[$key]+x} ]]; then
+ DISABLED["$key"]=1
+ COMMENT["$key"]="$2"
+ else
+ warn_unknown_flag "$raw" "$BOARD"
+ fi
+} # set_flag
+
+clear_flags() {
+ local k
+ for k in "${!DISABLED[@]}"; do
+ unset -v "DISABLED[$k]"
+ unset -v "COMMENT[$k]"
+ done
+ THIS_FOUND_FLAG=0
+} # clear_flags
+
+is_disabled() {
+ # return 0 if disabled for this FQBN, else 1
+ local key
+ key=$(norm_key "$1")
+ # echo "checking $key"
+ if [[ -n ${DISABLED[$key]+x} ]]; then
+ return 0
+ else
+ return 1
+ fi
+} # is_disabled
+
+comment_for() {
+ local key
+ key=$(norm_key "$1")
+ printf '%s' "${COMMENT[$key]}"
+} # comment_for
+
+has_comment() {
+ local key value
+ key=$(norm_key "$1")
+
+ # Key must exist
+ if [[ ! -v COMMENT[$key] ]]; then
+ return 1
+ fi
+
+ value=${COMMENT[$key]}
+
+ # Remove all whitespace for the check
+ local trimmed="${value//[[:space:]]/}"
+
+ if [[ -n $trimmed ]]; then
+ return 0 # true: (not and error) has a non-blank comment
+ else
+ return 1 # false: (error) empty or whitespace only
+ fi
+} # has_comment
+
+# Optional for each EXAMPLE / BOARD
+#
+#while IFS= read -r EXAMPLE; do
+# echo "Checking example: for $EXAMPLE"
+# while IFS= read -r BOARD; do
+# # Clean board names,
+# BOARD="${BOARD//$'\r'/}" # Remove carriage returns from the line
+#
+# # Skip any non-board fqbn lines
+# if [[ "$BOARD" =~ ^[[:space:]]*$ ]]; then
+# continue #skip blank lines
+# fi#
+#
+# if [[ "$BOARD" == \#* || "$BOARD" == " "*#* ]]; then
+# continue # Skip comments and lines starting with space + #
+# fi
+#
+# echo "Checking $EXAMPLE for $BOARD"
+
+
+# *************************************************************************************
+#
+discover_examples
+build_valid_examples
+# *************************************************************************************
+
+peek=
+echo "Here we go!"
+
+#*************************************************************************************
+# Read fqbn BOARD from $BOARD_LIST (typically ./board_list.txt)
+#*************************************************************************************
+while :; do
+ # read next FQBN line, some next lines might be hints to disable compile: --no-[n]
+ if [[ -n $peek ]]; then
+ line=$peek
+ peek=
+ else
+ IFS= read -r line || break
+ fi
+
+ line=$(strip_cr "$line")
+ if [[ "$line" == "exit" ]]; then
+ echo "Encountered exit in $BOARD_LIST; aborting"
+ break
+ fi
+
+
+ if is_skip "$line"; then
+ # echo "This line skipped: $line"
+ continue
+ fi
+
+ BOARD="${line//$'\r'/}" # Remove carriage returns from the line
+
+ echo ""
+ echo "*************************************************************************************"
+ echo "Testing board: $BOARD"
+ echo "*************************************************************************************"
+
+ echo "Checking flags..."
+ clear_flags
+
+ # collect any --no- lines under this FQBN
+ while IFS= read -r next; do
+ next=$(strip_cr "$next")
+
+ # echo "--calling is_skip with next=$next"
+ if is_skip "$next"; then
+ # echo "--skip! $next"
+ continue
+ fi
+
+ # echo " checking [$next] is like --no"
+ if [[ $LINE_VALUE == --no-* ]]; then
+ if [[ -n "$LINE_COMMENT" ]]; then
+ echo "$LINE_VALUE: $LINE_COMMENT"
+ else
+ echo "$LINE_VALUE: (No comment provided; Consider adding reason in $BOARD_LIST)"
+ fi
+ set_flag "$LINE_VALUE" "$LINE_COMMENT"
+ THIS_FOUND_FLAG=1
+ continue
+ # else
+ # not a line stat starts with --no
+ fi
+
+ peek=$next
+ break
+ done
+ if [[ $THIS_FOUND_FLAG -ne 0 ]]; then
+ echo "-------------------------------------------------------------------------------------"
+ fi
+
+ # echo "Flags done..."
+
+ # Typically at the end, or when multiple blank lines encountered
+ # if [[ -z $next && -z $peek ]]; then
+ # echo "Continue, skipping blank line..."
+ # continue
+ # fi
+ echo "Begin Board: $BOARD"
+
+ echo "-------------------------------------------------------------------------------------"
+ ((BOARD_CT++))
+ THIS_EXAMPLE_CT=0
+ for EXAMPLE in "${EXAMPLES[@]}"; do
+ start_time=$(date +%s) # record start time (epoch seconds)
+ echo "Checking $EXAMPLE for $BOARD"
+ if is_disabled "$EXAMPLE"; then
+ echo "Skipped"
+ ((BOARD_SKIP_CT++))
+
+ if has_comment "$EXAMPLE"; then
+ this_comment=$(comment_for "$EXAMPLE")
+ echo "Comment: $this_comment"
+ else
+ echo "No comment in $BOARD_LIST for disable reason on $EXAMPLE example."
+ fi
+ else
+ # If otherwise not excluded, compile this $EXAMPLE for this $BOARD
+ ((BOARD_COMPILE_CT++))
+ echo "arduino-cli compile --fqbn \"$BOARD\" \"$EXAMPLE\""
+ arduino-cli compile --fqbn "$BOARD" "$EXAMPLE"
+ EXIT_CODE=$?
+ if [ $EXIT_CODE -ne 0 ]; then
+ echo "$ICON_FAIL Compilation failed for $EXAMPLE on $BOARD (Exit code: $EXIT_CODE)"
+ ((BOARD_FAIL_CT++))
+ SUCCESS=false
+ SUMMARY_STATUS+=("$ICON_FAIL")
+ else
+ echo "$ICON_OK Compilation succeeded for $EXAMPLE on $BOARD"
+ SUMMARY_STATUS+=("$ICON_OK")
+ fi # exit code
+
+ SUMMARY_BOARD+=("$BOARD")
+ SUMMARY_EXAMPLE+=("$EXAMPLE")
+ fi # is_disabled check
+
+ end_time=$(date +%s) # record end time
+ elapsed=$(( end_time - start_time ))
+ echo "Block took ${elapsed} seconds"
+
+ if [[ $THIS_EXAMPLE_CT -lt $EXAMPLE_CT ]]; then
+ echo "-------------------------------------------------------------------------------------"
+ fi
+ ((THIS_EXAMPLE_CT++))
+ done # for each example
+done < "$BOARD_LIST" # for each BOARD
+
+
+# Optional for each EXAMPLE / BOARD
+#
+# done < board_list.txt # for each BOARD
+#done < <(find ./sketches -mindepth 1 -maxdepth 1 -type d) # for each EXAMPLE directory name
+
+echo "Done!"
+echo "-------------------------------------------------------------------------------------"
+echo "Boards found: $BOARD_CT"
+echo "Examples found: $EXAMPLE_CT"
+echo "Board Examples: $(( ${BOARD_CT:-0} * ${EXAMPLE_CT:-0} ))"
+echo "Compilation Summary:"
+printf "%-4s %-*s %-*s\n" "STAT" "$MAX_FQBN_LEN" "EXAMPLE" "$MAX_FQBN_LEN" "BOARD"
+printf "%-4s %-*s %-*s\n" "----" "$MAX_FQBN_LEN" "-------" "$MAX_FQBN_LEN" "-----"
+
+for i in "${!SUMMARY_STATUS[@]}"; do
+ printf "%-4s %-*s %-*s\n" \
+ "${SUMMARY_STATUS[$i]}" \
+ "$MAX_FQBN_LEN" "${SUMMARY_EXAMPLE[$i]}" \
+ "$MAX_FQBN_LEN" "${SUMMARY_BOARD[$i]}"
+done
+
+if [ "$SUCCESS" = true ]; then
+ echo "$ICON_OK All $BOARD_COMPILE_CT sketches compiled successfully! $BOARD_SKIP_CT board examples skipped (see $BOARD_LIST)."
+else
+ case "$BOARD_FAIL_CT" in
+ 0)
+ echo "$ICON_FAIL no sketches failed to compile. Other error?"
+ ;;
+ 1)
+ echo "$ICON_FAIL 1 sketch failed to compile."
+ ;;
+ *)
+ echo "$ICON_FAIL $BOARD_FAIL_CT sketches failed to compile."
+ ;;
+ esac
+
+ exit 1
+fi
diff --git a/Arduino/sketches/template/template.ino b/Arduino/sketches/template/template.ino
index 89989769..0d0f8d81 100644
--- a/Arduino/sketches/template/template.ino
+++ b/Arduino/sketches/template/template.ino
@@ -6,7 +6,7 @@
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
@@ -21,6 +21,13 @@
#include
+#if defined(ARDUINO_PORTENTA_X8)
+ /* The Portenta is a Linux device. See wolfSSL examples:
+ * https://github.com/wolfSSL/wolfssl/tree/master/examples
+ * By default Serial is disabled and mapped to ErrorSerial */
+ #include
+#endif
+
/* wolfSSL user_settings.h must be included from settings.h
* Make all configurations changes in user_settings.h
* Do not edit wolfSSL `settings.h` or `config.h` files.
diff --git a/Arduino/sketches/template/wolfssl_helper.c b/Arduino/sketches/template/wolfssl_helper.c
index f4eeb573..c6dcd39e 100644
--- a/Arduino/sketches/template/wolfssl_helper.c
+++ b/Arduino/sketches/template/wolfssl_helper.c
@@ -6,7 +6,7 @@
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
@@ -26,10 +26,36 @@
* Be sure to include these files in all libraries that reference
* wolfssl in this order: */
-#include
-/* settings.h is typically included in wolfssl.h, but here as a reminder: */
-#include
-#include
+#if defined(ARDUINO_PORTENTA_X8)
+ /* This file is purposely a c and not .cpp file for testing.
+ * On Portenta X8 the core headers assume C++, and things like A6,
+ * PIN_SPI_MOSI, etc. - rely on C++-only constructs.
+ * So don't include Arduino.h here for Portenta. */
+
+ #include
+ #include /* The ssl.h usually included by wolfssl.h */
+
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+
+ /* Sample source code is C, but Arduino is compiling with C++
+ * Declare a helper function to be used in wolfssl/wolfcrypt/logging.c */
+ int wolfSSL_Arduino_Serial_Print(const char* const s);
+
+ #ifdef __cplusplus
+ }
+ #endif
+#else
+ /* Assume all other target boards would want to include Arduino.h in a
+ * helper such as this one. Not needed in this wolfssl_helper.c example. */
+ #include
+
+ /* settings.h is typically included in wolfssl.h, but here as a reminder: */
+ #include
+ #include /* The wolfssl core Arduino library file */
+#endif
+
#include "wolfssl_helper.h"
diff --git a/Arduino/sketches/template/wolfssl_helper.h b/Arduino/sketches/template/wolfssl_helper.h
index 844f0223..1291dbe0 100644
--- a/Arduino/sketches/template/wolfssl_helper.h
+++ b/Arduino/sketches/template/wolfssl_helper.h
@@ -6,7 +6,7 @@
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
diff --git a/Arduino/sketches/wolfssl_AES_CTR/wolfssl_AES_CTR.ino b/Arduino/sketches/wolfssl_AES_CTR/wolfssl_AES_CTR.ino
index 31ef7973..a47d096e 100644
--- a/Arduino/sketches/wolfssl_AES_CTR/wolfssl_AES_CTR.ino
+++ b/Arduino/sketches/wolfssl_AES_CTR/wolfssl_AES_CTR.ino
@@ -6,7 +6,7 @@
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
@@ -19,6 +19,15 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
+#include
+
+#if defined(ARDUINO_PORTENTA_X8)
+ /* The Portenta is a Linux device. See wolfSSL examples:
+ * https://github.com/wolfSSL/wolfssl/tree/master/examples
+ * By default Serial is disabled and mapped to ErrorSerial */
+ #include
+#endif
+
/*
The Advanced Encryption Standard (AES) is a specification for the encryption of electronic
data established by the U.S. National Institute of Standards and Technology (NIST) in 2001.
@@ -50,7 +59,21 @@ Teensy 4.1 (ARM Cortex M7)
*/
#define WOLFSSL_AES_CTR_EXAMPLE
+/* wolfSSL user_settings.h must be included from settings.h
+ * Make all configurations changes in user_settings.h
+ * Do not edit wolfSSL `settings.h` or `config.h` files.
+ * Do not explicitly include user_settings.h in any source code.
+ * Each Arduino sketch that uses wolfSSL must have: #include "wolfssl.h"
+ * C/C++ source files can use: #include
+ * The wolfSSL "settings.h" must be included in each source file using wolfSSL.
+ * The wolfSSL "settings.h" must appear before any other wolfSSL include.
+ */
#include
+
+ /* settings.h is included from Arduino `wolfssl.h`, but a good practice to
+ * include before any other wolfssl headers. As a reminder here: */
+#include
+
#include
#if defined(NO_AES) or !defined(WOLFSSL_AES_COUNTER) or !defined(WOLFSSL_AES_128)
diff --git a/Arduino/sketches/wolfssl_client/wolfssl_client.ino b/Arduino/sketches/wolfssl_client/wolfssl_client.ino
index 8af1eafe..c56de7fd 100644
--- a/Arduino/sketches/wolfssl_client/wolfssl_client.ino
+++ b/Arduino/sketches/wolfssl_client/wolfssl_client.ino
@@ -6,7 +6,7 @@
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
@@ -39,6 +39,18 @@ Tested with:
/* If you have a private include, define it here, otherwise edit WiFi params */
/* #define MY_PRIVATE_CONFIG "/workspace/my_private_config.h" */
+#if defined(ARDUINO) && defined(ESP8266)
+ #warning "This example is not yet supported on Arduino ESP8266"
+#endif
+
+#if defined(DEBUG_WOLFSSL)
+ /* Optionally enabled verbose wolfSSL debugging */
+ #define DEBUG_WOLFSSL_MESSAGES_ON
+#else
+ /* DEBUG_WOLFSSL needs to be enabled */
+ #undef DEBUG_WOLFSSL_MESSAGES_ON
+#endif
+
/* set REPEAT_CONNECTION to a non-zero value to continually run the example. */
#define REPEAT_CONNECTION 0
@@ -68,12 +80,12 @@ Tested with:
/* the /workspace directory may contain a private config
* excluded from GitHub with items such as WiFi passwords */
#include MY_PRIVATE_CONFIG
- static const char ssid[] PROGMEM = MY_ARDUINO_WIFI_SSID;
- static const char password[] PROGMEM = MY_ARDUINO_WIFI_PASSWORD;
+ static const char ssid[] PROGMEM = MY_ARDUINO_WIFI_SSID;
+ static const char password[] PROGMEM = MY_ARDUINO_WIFI_PASSWORD;
#else
/* when using WiFi capable boards: */
- static const char ssid[] PROGMEM = "your_SSID";
- static const char password[] PROGMEM = "your_PASSWORD";
+ static const char ssid[] PROGMEM = "your_SSID";
+ static const char password[] PROGMEM = "your_PASSWORD";
#endif
#define BROADCAST_ADDRESS "255.255.255.255"
@@ -132,6 +144,10 @@ Tested with:
#elif defined(ESP8266)
#define USING_WIFI
#include
+ /* Ensure the F() flash macro is defined */
+ #ifndef F
+ #define F
+ #endif
WiFiClient client;
#elif defined(ARDUINO_SAM_DUE)
@@ -140,7 +156,10 @@ Tested with:
/* Needs "Ethernet by Various" library to be installed. Tested with V2.0.2 */
#include
EthernetClient client;
-
+#elif defined(ARDUINO_AVR_ETHERNET) || defined(ARDUINO_AVR_LEONARDO_ETH)
+ /* Boards such as arduino:avr:ethernet and arduino:avr:leonardoeth */
+ #include
+ EthernetClient client;
#elif defined(ARDUINO_SAMD_NANO_33_IOT)
#define USING_WIFI
#include
@@ -153,6 +172,36 @@ Tested with:
#include
WiFiClient client;
+#elif defined(ARDUINO_SAMD_TIAN)
+ #include
+ #include
+ HttpClient client;
+ /* Arduino Tian does not support network shields like the standard Ethernet or Wi-Fi shields. */
+ #error "HttpClient cannot be used for this example"
+#elif defined(ARDUINO_PORTENTA_X8)
+ /* The Portenta is a Linux device. See wolfSSL examples:
+ * https://github.com/wolfSSL/wolfssl/tree/master/examples
+ * By default Serial is disabled and mapped to ErrorSerial */
+ #include
+
+ /* ----No - network placeholders(compile - only) ---- */
+ #include
+ struct X8NoNetClient {
+ int write(const uint8_t*, size_t) { return -1; }
+ int available() { return 0; }
+ int read() { return -1; }
+ void stop() {}
+ bool connected() { return false; }
+ IPAddress remoteIP() { return IPAddress(0, 0, 0, 0); }
+ };
+ struct X8NoNetServer {
+ explicit X8NoNetServer(uint16_t) {}
+ void begin() {}
+ X8NoNetClient available() { return X8NoNetClient(); }
+ };
+
+ X8NoNetClient client;
+ X8NoNetServer server(WOLFSSL_PORT);
#elif defined(USING_WIFI)
#define USING_WIFI
#include
@@ -205,7 +254,10 @@ static char errBuf[80];
static int EthernetSend(WOLFSSL* ssl, char* msg, int sz, void* ctx);
static int EthernetReceive(WOLFSSL* ssl, char* reply, int sz, void* ctx);
static int reconnect = RECONNECT_ATTEMPTS;
+#if 0
+/* optional showPeerEx, currently disabled */
static int lng_index PROGMEM = 0; /* 0 = English */
+#endif
#if defined(__arm__)
#include
@@ -462,7 +514,8 @@ int setup_network(void) {
/*****************************************************************************/
/* Arduino setup_wolfssl() */
/*****************************************************************************/
-int setup_wolfssl(void) {
+int setup_wolfssl(void)
+{
int ret = 0;
WOLFSSL_METHOD* method;
@@ -482,8 +535,14 @@ int setup_wolfssl(void) {
#endif
#if defined(DEBUG_WOLFSSL)
- wolfSSL_Debugging_ON();
- Serial.println(F("wolfSSL Debugging is On!"));
+ Serial.println(F("wolfSSL Debugging is available! (DEBUG_WOLFSSL)"));
+ #if defined(DEBUG_WOLFSSL_MESSAGES_ON)
+ Serial.println(F("Enabling verbose messages wolfSSL_Debugging_ON"));
+ wolfSSL_Debugging_ON();
+ #else
+ Serial.println(F("Enable verbose messages with wolfSSL_Debugging_ON"));
+ Serial.println(F("or define DEBUG_WOLFSSL_MESSAGES_ON"));
+ #endif
#else
Serial.println(F("wolfSSL Debugging is Off! (enable with DEBUG_WOLFSSL)"));
#endif
@@ -509,6 +568,7 @@ int setup_wolfssl(void) {
* It is best on embedded devices to choose a TLS session cache size. */
#endif
+ /* Initialize wolfSSL before assigning ctx */
ret = wolfSSL_Init();
if (ret == WOLFSSL_SUCCESS) {
Serial.println("Successfully called wolfSSL_Init");
@@ -543,7 +603,8 @@ int setup_wolfssl(void) {
/*****************************************************************************/
/* Arduino setup_certificates() */
/*****************************************************************************/
-int setup_certificates(void) {
+int setup_certificates(void)
+{
int ret = 0;
Serial.println(F("Initializing certificates..."));
@@ -609,7 +670,8 @@ int setup_certificates(void) {
/* Arduino setup() */
/*****************************************************************************/
/*****************************************************************************/
-void setup(void) {
+void setup(void)
+{
int i = 0;
Serial.begin(SERIAL_BAUD);
while (!Serial && (i < 10)) {
@@ -650,13 +712,17 @@ void setup(void) {
wolfSSL_SetIOSend(ctx, EthernetSend);
wolfSSL_SetIORecv(ctx, EthernetReceive);
+#if defined THIS_USER_SETTINGS_VERSION
+ Serial.print(F("This user_settings.h version:"))
+ Serial.println(THIS_USER_SETTINGS_VERSION)
+#endif
+
Serial.println(F("Completed Arduino setup!"));
/* See companion wolfssl_server.ino code; server begins listening here
* https://github.com/wolfSSL/wolfssl/tree/master/IDE/ARDUINO/sketches/wolfssl_server
* Any other server will work. See also:
* https://github.com/wolfSSL/wolfssl/tree/master/examples/client
*/
- /* See companion wolfssl_server.ino code */
return;
} /* Arduino setup */
@@ -731,7 +797,7 @@ int error_check_ssl(WOLFSSL* ssl, int this_ret, bool halt_on_error,
}
return err;
-}
+} /* error_check_ssl */
/*****************************************************************************/
/*****************************************************************************/
diff --git a/Arduino/sketches/wolfssl_client_dtls/README.md b/Arduino/sketches/wolfssl_client_dtls/README.md
new file mode 100644
index 00000000..924225b7
--- /dev/null
+++ b/Arduino/sketches/wolfssl_client_dtls/README.md
@@ -0,0 +1,28 @@
+# Arduino Basic DTLS Listening Client
+
+Open the [wolfssl_client_dtls.ino](./wolfssl_client_dtls.ino) file in the Arduino IDE.
+
+If using WiFi, be sure to set `ssid` and `password` values.
+
+May need "Ethernet by Various" library to be installed. Tested with v2.0.2 and v2.8.1.
+
+See the `#define WOLFSSL_TLS_SERVER_HOST` to set your own server address.
+
+Other IDE products are also supported, such as:
+
+- [PlatformIO in VS Code](https://docs.platformio.org/en/latest/frameworks/arduino.html)
+- [VisualGDB](https://visualgdb.com/tutorials/arduino/)
+- [VisualMicro](https://www.visualmicro.com/)
+
+For examples on other platforms, see the [IDE directory](https://github.com/wolfssl/wolfssl/tree/master/IDE).
+Additional examples can be found on [wolfSSL/wolfssl-examples](https://github.com/wolfSSL/wolfssl-examples/).
+
+
+### Troubleshooting
+
+When encountering odd errors such as `undefined reference to ``_impure_ptr'`, try cleaning the Arduino
+cache directories. For Windows, that's typically in:
+
+```text
+C:\Users\%USERNAME%\AppData\Local\Temp\arduino\sketches
+```
diff --git a/Arduino/sketches/wolfssl_client_dtls/wolfssl_client_dtls.ino b/Arduino/sketches/wolfssl_client_dtls/wolfssl_client_dtls.ino
new file mode 100644
index 00000000..e4e8fec6
--- /dev/null
+++ b/Arduino/sketches/wolfssl_client_dtls/wolfssl_client_dtls.ino
@@ -0,0 +1,950 @@
+/*
+ * client-dtls13.c
+ *
+ * Copyright (C) 2006-2025 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ *
+ *=============================================================================
+ *
+ * Bare-bones example of a DTLS 1.3 client for instructional/learning purposes.
+ * This example uses blocking sockets for simplicity.
+ *
+ * Define USE_DTLS12 to use DTLS 1.2 instead of DTLS 1.3
+/*
+Tested with:
+
+1) Intel Galileo acting as the Client, with a laptop acting as a server using
+ the server example provided in examples/server.
+ Legacy Arduino v1.86 was used to compile and program the Galileo
+
+2) Espressif ESP32 WiFi
+
+3) Arduino Due, Nano33 IoT, Nano RP-2040
+*/
+
+/*
+ * Note to code editors: the Arduino client and server examples are edited in
+ * parallel for side-by-side comparison between examples.
+ */
+
+/* If you have a private include, define it here, otherwise edit WiFi params */
+/* #define MY_PRIVATE_CONFIG "/workspace/my_private_config.h" */
+
+#if defined(ARDUINO) && defined(ESP8266)
+ #warning "This example is not yet supported on Arduino ESP8266"
+#endif
+
+#if defined(DEBUG_WOLFSSL)
+ /* Optionally enabled verbose wolfSSL debugging */
+ #define DEBUG_WOLFSSL_MESSAGES_ON
+#else
+ /* DEBUG_WOLFSSL needs to be enabled */
+ #undef DEBUG_WOLFSSL_MESSAGES_ON
+#endif
+
+/* set REPEAT_CONNECTION to a non-zero value to continually run the example. */
+#define REPEAT_CONNECTION 0
+
+/* Edit this with your other DTLS host server address to connect to: */
+#define WOLFSSL_DTLS_SERVER_HOST "192.168.1.107"
+
+/* wolfssl TLS examples communicate on port 11111 */
+#define WOLFSSL_PORT 11111
+
+/* Choose a monitor serial baud rate: 9600, 14400, 19200, 57600, 74880, etc. */
+#define SERIAL_BAUD 115200
+
+/* We'll wait up to 2000 milliseconds to properly shut down connection */
+#define SHUTDOWN_DELAY_MS 2000
+
+/* Number of times to retry connection. */
+#define RECONNECT_ATTEMPTS 20
+
+/* Number of DTLS messages to send. Use -1 for continual messages. */
+#define DTLS_MESSAGE_CT 42
+
+/* Assume bad socket until proven otherwise */
+#define INVALID_SOCKET -1
+
+/* Maximum size in bytes of buffer to send and receive */
+#define MAXLINE 128
+
+/* Optional stress test. Define to consume memory until exhausted: */
+/* #define MEMORY_STRESS_TEST */
+
+/* Choose client or server example, not both. */
+#define WOLFSSL_CLIENT_EXAMPLE
+/* #define WOLFSSL_SERVER_EXAMPLE */
+
+#if defined(MY_PRIVATE_CONFIG)
+ /* the /workspace directory may contain a private config
+ * excluded from GitHub with items such as WiFi passwords */
+ #include MY_PRIVATE_CONFIG
+ static const char ssid[] PROGMEM = MY_ARDUINO_WIFI_SSID;
+ static const char password[] PROGMEM = MY_ARDUINO_WIFI_PASSWORD;
+#else
+ /* when using WiFi capable boards: */
+ static const char ssid[] PROGMEM = "your_SSID";
+ static const char password[] PROGMEM = "your_PASSWORD";
+#endif
+
+#define BROADCAST_ADDRESS "255.255.255.255"
+
+/* There's an optional 3rd party NTPClient library by Fabrice Weinberg.
+ * If it is installed, uncomment define USE_NTP_LIB here: */
+/* #define USE_NTP_LIB */
+#ifdef USE_NTP_LIB
+ #include
+#endif
+
+/* wolfSSL user_settings.h must be included from settings.h
+ * Make all configurations changes in user_settings.h
+ * Do not edit wolfSSL `settings.h` or `config.h` files.
+ * Do not explicitly include user_settings.h in any source code.
+ * Each Arduino sketch that uses wolfSSL must have: #include "wolfssl.h"
+ * C/C++ source files can use: #include
+ * The wolfSSL "settings.h" must be included in each source file using wolfSSL.
+ * The wolfSSL "settings.h" must appear before any other wolfSSL include.
+ */
+#include
+/* Important: make sure settings.h appears before any other wolfSSL headers */
+#include
+/* Reminder: settings.h includes user_settings.h
+ * For ALL project wolfSSL settings, see:
+ * [your path]/Arduino\libraries\wolfSSL\src\user_settings.h */
+#include
+#include
+#include
+
+#ifndef WOLFSSL_DTLS
+ /* Support for DTLS by default was added after wolfSSL v5.8.2 release */
+ #error "This example requires WOLFSSL_DTLS. See user_settings.h in the Arduino wolfssl library"
+#endif
+
+/* Define DEBUG_WOLFSSL in user_settings.h for more verbose logging. */
+#if defined(DEBUG_WOLFSSL)
+ #define PROGRESS_DOT F("")
+#else
+ #define PROGRESS_DOT F(".")
+#endif
+
+/* Convert a macro to a string */
+#define xstr(x) str(x)
+#define str(x) #x
+
+/* optional board-specific networking includes */
+#if defined(ESP32)
+ #define USING_WIFI
+ #include
+ #include
+ #ifdef USE_NTP_LIB
+ WiFiUDP ntpUDP;
+ #endif
+ /* Ensure the F() flash macro is defined */
+ #ifndef F
+ #define F
+ #endif
+ WiFiClient client;
+
+#elif defined(ESP8266)
+ #define USING_WIFI
+ #include
+ WiFiClient client;
+
+#elif defined(ARDUINO_SAM_DUE)
+ #include
+ /* There's no WiFi/Ethernet on the Due. Requires Ethernet Shield.
+ /* Needs "Ethernet by Various" library to be installed. Tested with V2.0.2 */
+ #include
+ EthernetClient client;
+#elif defined(ARDUINO_AVR_ETHERNET) || defined(ARDUINO_AVR_LEONARDO_ETH)
+ /* Boards such as arduino:avr:ethernet and arduino:avr:leonardoeth */
+ #include
+ EthernetClient client;
+
+#elif defined(ARDUINO_SAMD_NANO_33_IOT)
+ #define USING_WIFI
+ #include
+ #include /* Needs Arduino WiFiNINA library installed manually */
+ WiFiClient client;
+
+#elif defined(ARDUINO_ARCH_RP2040)
+ #define USING_WIFI
+ #include
+ #include
+ WiFiClient client;
+
+#elif defined(ARDUINO_SAMD_TIAN)
+ #include
+ #include
+ HttpClient client;
+ /* Arduino Tian does not support network shields like the standard Ethernet or Wi-Fi shields. */
+ #error "HttpClient cannot be used for this example"
+#elif defined(ARDUINO_PORTENTA_X8)
+ /* The Portenta is a Linux device. See wolfSSL examples:
+ * https://github.com/wolfSSL/wolfssl/tree/master/examples
+ * By default Serial is disabled and mapped to ErrorSerial */
+ #include
+
+ /* ----No - network placeholders(compile - only) ---- */
+ #include
+ struct X8NoNetClient {
+ int write(const uint8_t*, size_t) { return -1; }
+ int available() { return 0; }
+ int read() { return -1; }
+ void stop() {}
+ bool connected() { return false; }
+ IPAddress remoteIP() { return IPAddress(0, 0, 0, 0); }
+ };
+ struct X8NoNetServer {
+ explicit X8NoNetServer(uint16_t) {}
+ void begin() {}
+ X8NoNetClient available() { return X8NoNetClient(); }
+ };
+
+ X8NoNetClient client;
+ X8NoNetServer server(WOLFSSL_PORT);
+#elif defined(USING_WIFI)
+ #define USING_WIFI
+ #include
+ #include
+ #ifdef USE_NTP_LIB
+ WiFiUDP ntpUDP;
+ #endif
+ WiFiClient client;
+
+/* TODO
+#elif defined(OTHER_BOARD)
+*/
+#else
+ /* assume all other boards using WiFi library. Edit as needed: */
+ #include
+ #define USING_WIFI
+ WiFiClient client;
+#endif
+
+/* Only for syntax highlighters to show interesting options enabled: */
+#if defined(HAVE_SNI) \
+ || defined(HAVE_MAX_FRAGMENT) \
+ || defined(HAVE_TRUSTED_CA) \
+ || defined(HAVE_TRUNCATED_HMAC) \
+ || defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
+ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) \
+ || defined(HAVE_SUPPORTED_CURVES) \
+ || defined(HAVE_ALPN) \
+ || defined(HAVE_SESSION_TICKET) \
+ || defined(HAVE_SECURE_RENEGOTIATION) \
+ || defined(HAVE_SERVER_RENEGOTIATION_INFO)
+#endif
+
+static const char host[] PROGMEM = WOLFSSL_DTLS_SERVER_HOST; /* server to connect to */
+static const int port PROGMEM = WOLFSSL_PORT; /* port on server to connect to */
+
+static WOLFSSL_CTX* ctx = NULL;
+static WOLFSSL* ssl = NULL;
+static char* wc_error_message = (char*)malloc(80 + 1);
+static char errBuf[80];
+
+#if defined(MEMORY_STRESS_TEST)
+ #define MEMORY_STRESS_ITERATIONS 100
+ #define MEMORY_STRESS_BLOCK_SIZE 1024
+ #define MEMORY_STRESS_INITIAL (4*1024)
+ static char* memory_stress[MEMORY_STRESS_ITERATIONS]; /* typically 1K per item */
+ static int mem_ctr = 0;
+#endif
+
+static int EthernetSend(WOLFSSL* ssl, char* msg, int sz, void* ctx);
+static int EthernetReceive(WOLFSSL* ssl, char* reply, int sz, void* ctx);
+static int reconnect = RECONNECT_ATTEMPTS;
+#if 0
+/* optional showPeerEx, currently disabled */
+static int lng_index PROGMEM = 0; /* 0 = English */
+#endif
+
+#if defined(__arm__)
+ #include
+ extern char _end;
+ extern "C" char *sbrk(int i);
+ static char *ramstart=(char *)0x20070000;
+ static char *ramend=(char *)0x20088000;
+#endif
+
+/*****************************************************************************/
+/* fail_wait - in case of unrecoverable error */
+/*****************************************************************************/
+int fail_wait(void) {
+ show_memory();
+
+ Serial.println(F("Failed. Halt."));
+ while (1) {
+ delay(1000);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+/* show_memory() to optionally view during debugging. */
+/*****************************************************************************/
+int show_memory(void)
+{
+#if defined(__arm__)
+ struct mallinfo mi = mallinfo();
+
+ char *heapend=sbrk(0);
+ register char * stack_ptr asm("sp");
+ #if defined(DEBUG_WOLFSSL_VERBOSE)
+ Serial.print(" arena=");
+ Serial.println(mi.arena);
+ Serial.print(" ordblks=");
+ Serial.println(mi.ordblks);
+ Serial.print(" uordblks=");
+ Serial.println(mi.uordblks);
+ Serial.print(" fordblks=");
+ Serial.println(mi.fordblks);
+ Serial.print(" keepcost=");
+ Serial.println(mi.keepcost);
+ #endif
+
+ #if defined(DEBUG_WOLFSSL) || defined(MEMORY_STRESS_TEST)
+ Serial.print("Estimated free memory: ");
+ Serial.print(stack_ptr - heapend + mi.fordblks);
+ Serial.println(F(" bytes"));
+ #endif
+
+ #if (0)
+ /* Experimental: not supported on all devices: */
+ Serial.print("RAM Start %lx\n", (unsigned long)ramstart);
+ Serial.print("Data/Bss end %lx\n", (unsigned long)&_end);
+ Serial.print("Heap End %lx\n", (unsigned long)heapend);
+ Serial.print("Stack Ptr %lx\n",(unsigned long)stack_ptr);
+ Serial.print("RAM End %lx\n", (unsigned long)ramend);
+
+ Serial.print("Heap RAM Used: ",mi.uordblks);
+ Serial.print("Program RAM Used ",&_end - ramstart);
+ Serial.print("Stack RAM Used ",ramend - stack_ptr);
+
+ Serial.print("Estimated Free RAM: %d\n\n",stack_ptr - heapend + mi.fordblks);
+ #endif
+#else
+ Serial.println(F("show_memory() not implemented for this platform"));
+#endif
+ return 0;
+}
+
+/*****************************************************************************/
+/* Arduino setup_hardware() */
+/*****************************************************************************/
+int setup_hardware(void) {
+ int ret = 0;
+
+#if defined(ARDUINO_SAMD_NANO_33_IOT)
+ Serial.println(F("Detected known tested and working Arduino Nano 33 IoT"));
+#elif defined(ARDUINO_ARCH_RP2040)
+ Serial.println(F("Detected known tested and working Arduino RP-2040"));
+#elif defined(__arm__) && defined(ID_TRNG) && defined(TRNG)
+ /* need to manually turn on random number generator on Arduino Due, etc. */
+ pmc_enable_periph_clk(ID_TRNG);
+ trng_enable(TRNG);
+ Serial.println(F("Enabled ARM TRNG"));
+#endif
+
+ show_memory();
+ randomSeed(analogRead(0));
+ return ret;
+}
+
+/*****************************************************************************/
+/* Arduino setup_datetime() */
+/* The device needs to have a valid date within the valid range of certs. */
+/*****************************************************************************/
+int setup_datetime(void) {
+ int ret = 0;
+ int ntp_tries = 20;
+
+ /* we need a date in the range of cert expiration */
+#ifdef USE_NTP_LIB
+ #if defined(ESP32)
+ NTPClient timeClient(ntpUDP, "pool.ntp.org");
+
+ timeClient.begin();
+ timeClient.update();
+ delay(1000);
+ while (!timeClient.isTimeSet() && (ntp_tries > 0)) {
+ timeClient.forceUpdate();
+ Serial.println(F("Waiting for NTP update"));
+ delay(2000);
+ ntp_tries--;
+ }
+ if (ntp_tries <= 0) {
+ Serial.println(F("Warning: gave up waiting on NTP"));
+ }
+ Serial.println(timeClient.getFormattedTime());
+ Serial.println(timeClient.getEpochTime());
+ #endif
+#endif
+
+#if defined(ESP32)
+ /* see esp32-hal-time.c */
+ ntp_tries = 5;
+ /* Replace "pool.ntp.org" with your preferred NTP server */
+ configTime(0, 0, "pool.ntp.org");
+
+ /* Wait for time to be set */
+ while ((time(nullptr) <= 100000) && ntp_tries > 0) {
+ Serial.println(F("Waiting for time to be set..."));
+ delay(2000);
+ ntp_tries--;
+ }
+#endif
+
+ return ret;
+} /* setup_datetime */
+
+/*****************************************************************************/
+/* Arduino setup_network() */
+/*****************************************************************************/
+int setup_network(void) {
+ int ret = 0;
+
+#if defined(USING_WIFI)
+ int status = WL_IDLE_STATUS;
+
+ /* The ESP8266 & ESP32 support both AP and STA. We'll use STA: */
+ #if defined(ESP8266) || defined(ESP32)
+ WiFi.mode(WIFI_STA);
+ #else
+ String fv;
+ if (WiFi.status() == WL_NO_MODULE) {
+ Serial.println("Communication with WiFi module failed!");
+ /* don't continue if no network */
+ while (true) ;
+ }
+
+ fv = WiFi.firmwareVersion();
+ if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
+ Serial.println("Please upgrade the firmware");
+ }
+ #endif
+
+ Serial.print(F("Connecting to WiFi "));
+ Serial.print(ssid);
+ status = WiFi.begin(ssid, password);
+ while (status != WL_CONNECTED) {
+ delay(1000);
+ Serial.print(F("."));
+ Serial.print(status);
+ status = WiFi.status();
+ }
+
+ Serial.println(F(" Connected!"));
+#else
+ /* Newer Ethernet shields have a
+ * MAC address printed on a sticker on the shield */
+ byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
+ IPAddress ip(192, 168, 1, 42);
+ IPAddress myDns(192, 168, 1, 1);
+ Ethernet.init(10); /* Most Arduino shields */
+ /* Ethernet.init(5); * MKR ETH Shield */
+ /* Ethernet.init(0); * Teensy 2.0 */
+ /* Ethernet.init(20); * Teensy++ 2.0 */
+ /* Ethernet.init(15); * ESP8266 with Adafruit FeatherWing Ethernet */
+ /* Ethernet.init(33); * ESP32 with Adafruit FeatherWing Ethernet */
+ Serial.println(F("Initialize Ethernet with DHCP:"));
+ if (Ethernet.begin(mac) == 0) {
+ Serial.println(F("Failed to configure Ethernet using DHCP"));
+ /* Check for Ethernet hardware present */
+ if (Ethernet.hardwareStatus() == EthernetNoHardware) {
+ Serial.println(F("Ethernet shield was not found."));
+ while (true) {
+ delay(1); /* do nothing */
+ }
+ }
+ if (Ethernet.linkStatus() == LinkOFF) {
+ Serial.println(F("Ethernet cable is not connected."));
+ }
+ /* try to configure using IP address instead of DHCP : */
+ Ethernet.begin(mac, ip, myDns);
+ }
+ else {
+ Serial.print(F(" DHCP assigned IP "));
+ Serial.println(Ethernet.localIP());
+ }
+ /* We'll assume the Ethernet connection is ready to go. */
+#endif
+
+ Serial.println(F("********************************************************"));
+ Serial.print(F(" wolfSSL Example Client IP = "));
+#if defined(USING_WIFI)
+ Serial.println(WiFi.localIP());
+#else
+ Serial.println(Ethernet.localIP());
+#endif
+ Serial.print(F(" Configured Server Host to connect to: "));
+ Serial.println(host);
+ Serial.println(F("********************************************************"));
+ Serial.println(F("Setup network complete."));
+
+ return ret;
+}
+
+/*****************************************************************************/
+/* Arduino setup_wolfssl() */
+/*****************************************************************************/
+int setup_wolfssl(void)
+{
+ int ret = 0;
+ WOLFSSL_METHOD* method;
+
+ /* Show a revision of wolfssl user_settings.h file in use when available: */
+#if defined(WOLFSSL_USER_SETTINGS_ID)
+ Serial.print(F("WOLFSSL_USER_SETTINGS_ID: "));
+ Serial.println(F(WOLFSSL_USER_SETTINGS_ID));
+#else
+ Serial.println(F("No WOLFSSL_USER_SETTINGS_ID found."));
+#endif
+
+#if defined(NO_WOLFSSL_SERVER)
+ Serial.println(F("wolfSSL server code disabled to save space."));
+#endif
+#if defined(NO_WOLFSSL_CLIENT)
+ Serial.println(F("wolfSSL client code disabled to save space."));
+#endif
+
+#if defined(DEBUG_WOLFSSL)
+ Serial.println(F("wolfSSL Debugging is available! (DEBUG_WOLFSSL)"));
+ #if defined(DEBUG_WOLFSSL_MESSAGES_ON)
+ Serial.println(F("Enabling verbose messages wolfSSL_Debugging_ON"));
+ wolfSSL_Debugging_ON();
+ #else
+ Serial.println(F("Enable verbose messages with wolfSSL_Debugging_ON"));
+ Serial.println(F("or define DEBUG_WOLFSSL_MESSAGES_ON"));
+ #endif
+#else
+ Serial.println(F("wolfSSL Debugging is Off! (enable with DEBUG_WOLFSSL)"));
+#endif
+
+ /* See ssl.c for TLS cache settings. Larger cache = use more RAM. */
+#if defined(NO_SESSION_CACHE)
+ Serial.println(F("wolfSSL TLS NO_SESSION_CACHE"));
+#elif defined(MICRO_SESSION_CACHEx)
+ Serial.println(F("wolfSSL TLS MICRO_SESSION_CACHE"));
+#elif defined(SMALL_SESSION_CACHE)
+ Serial.println(F("wolfSSL TLS SMALL_SESSION_CACHE"));
+#elif defined(MEDIUM_SESSION_CACHE)
+ Serial.println(F("wolfSSL TLS MEDIUM_SESSION_CACHE"));
+#elif defined(BIG_SESSION_CACHE)
+ Serial.println(F("wolfSSL TLS BIG_SESSION_CACHE"));
+#elif defined(HUGE_SESSION_CACHE)
+ Serial.println(F("wolfSSL TLS HUGE_SESSION_CACHE"));
+#elif defined(HUGE_SESSION_CACHE)
+ Serial.println(F("wolfSSL TLS HUGE_SESSION_CACHE"));
+#else
+ Serial.println(F("WARNING: Unknown or no TLS session cache setting."));
+ /* See wolfssl/src/ssl.c for amount of memory used.
+ * It is best on embedded devices to choose a TLS session cache size. */
+#endif
+
+ /* Initialize wolfSSL before assigning ctx */
+ ret = wolfSSL_Init();
+ if (ret == WOLFSSL_SUCCESS) {
+ Serial.println("Successfully called wolfSSL_Init");
+ }
+ else {
+ Serial.println("ERROR: wolfSSL_Init failed");
+ }
+
+ /* See companion server example with wolfSSLv23_server_method here.
+ * method = wolfSSLv23_client_method()); SSL 3.0 - TLS 1.3.
+ * method = wolfTLSv1_2_client_method(); only TLS 1.2
+ * method = wolfTLSv1_3_client_method(); only TLS 1.3
+ *
+ * see Arduino\libraries\wolfssl\src\user_settings.h */
+
+ Serial.println("Here we go!");
+
+#ifdef WOLFSSL_DTLS13
+ Serial.println(F("Setting wolfDTLSv1_3_client_method"));
+ method = wolfDTLSv1_3_client_method();
+#else
+ Serial.println(F("Setting wolfDTLSv1_2_client_method"));
+ method = wolfDTLSv1_2_client_method();
+#endif
+ ctx = wolfSSL_CTX_new(method);
+ if (ctx == NULL) {
+ fail_wait();
+ }
+
+ if (method == NULL) {
+ Serial.println(F("Unable to get wolfssl client method"));
+ fail_wait();
+ }
+
+ ctx = wolfSSL_CTX_new(method);
+ if (ctx == NULL) {
+ Serial.println(F("unable to get ctx"));
+ fail_wait();
+ }
+
+ return ret;
+}
+
+/*****************************************************************************/
+/* Arduino setup_certificates() */
+/*****************************************************************************/
+int setup_certificates(void)
+{
+ int ret = 0;
+
+ /* See user_settings.h that should have included wolfssl/certs_test.h */
+
+ Serial.println(F("Initializing certificates..."));
+ show_memory();
+
+ /* Use built-in validation, No verification callback function: */
+ wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, 0);
+
+ /* Certificate */
+ Serial.println("Initializing certificates...");
+ ret = wolfSSL_CTX_use_certificate_buffer(ctx,
+ CTX_CLIENT_CERT,
+ CTX_CLIENT_CERT_SIZE,
+ CTX_CLIENT_CERT_TYPE);
+ if (ret == WOLFSSL_SUCCESS) {
+ Serial.print("Success: use certificate: ");
+ Serial.println(xstr(CTX_SERVER_CERT));
+ }
+ else {
+ Serial.println(F("Error: wolfSSL_CTX_use_certificate_buffer failed: "));
+ wc_ErrorString(ret, wc_error_message);
+ Serial.println(wc_error_message);
+ fail_wait();
+ }
+
+ /* Setup private client key */
+ ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx,
+ CTX_CLIENT_KEY,
+ CTX_CLIENT_KEY_SIZE,
+ CTX_CLIENT_KEY_TYPE);
+ if (ret == WOLFSSL_SUCCESS) {
+ Serial.print("Success: use private key buffer: ");
+ Serial.println(xstr(CTX_SERVER_KEY));
+ }
+ else {
+ Serial.println(F("Error: wolfSSL_CTX_use_PrivateKey_buffer failed: "));
+ wc_ErrorString(ret, wc_error_message);
+ Serial.println(wc_error_message);
+ fail_wait();
+ }
+
+ ret = wolfSSL_CTX_load_verify_buffer(ctx,
+ CTX_CA_CERT,
+ CTX_CA_CERT_SIZE,
+ CTX_CA_CERT_TYPE);
+ if (ret == WOLFSSL_SUCCESS) {
+ Serial.println(F("Success: load_verify CTX_CA_CERT"));
+ }
+ else {
+ Serial.println(F("Error: wolfSSL_CTX_load_verify_buffer failed: "));
+ wc_ErrorString(ret, wc_error_message);
+ Serial.println(wc_error_message);
+ fail_wait();
+ }
+
+ return ret;
+} /* Arduino setup */
+
+/*****************************************************************************/
+/*****************************************************************************/
+/* Arduino setup() */
+/*****************************************************************************/
+/*****************************************************************************/
+void setup(void) {
+ int i = 0;
+ Serial.begin(SERIAL_BAUD);
+ while (!Serial && (i < 10)) {
+ /* wait for serial port to connect. Needed for native USB port only */
+ delay(1000);
+ i++;
+ }
+ Serial.println(F(""));
+ Serial.println(F(""));
+ Serial.println(F("wolfSSL DTLS Client Example Startup."));
+
+ /* Optionally pre-allocate a large block of memory for testing */
+#if defined(MEMORY_STRESS_TEST)
+ Serial.println(F("WARNING: Memory Stress Test Active!"));
+ Serial.print(F("Allocating extra memory: "));
+ Serial.print(MEMORY_STRESS_INITIAL);
+ Serial.println(F(" bytes..."));
+ memory_stress[mem_ctr] = (char*)malloc(MEMORY_STRESS_INITIAL);
+ show_memory();
+#endif
+
+ setup_hardware();
+
+ setup_network();
+
+ setup_datetime();
+
+ setup_wolfssl();
+
+ setup_certificates();
+
+#if defined THIS_USER_SETTINGS_VERSION
+ Serial.print(F("This user_settings.h version:"))
+ Serial.println(THIS_USER_SETTINGS_VERSION)
+#endif
+
+ Serial.println(F("Completed Arduino setup!"));
+ /* See companion wolfssl_server_dtls.ino code; server begins listening here
+ * https://github.com/wolfSSL/wolfssl-examples/tree/master/Arduino/sketches/wolfssl_server_dtls
+ * Any other DTLS server will work. See also:
+ * https://github.com/wolfSSL/wolfssl/tree/master/examples/client
+ */
+ return;
+} /* Arduino setup */
+
+/*****************************************************************************/
+/* wolfSSL error_check() */
+/*****************************************************************************/
+int error_check(int this_ret, bool halt_on_error,
+ const __FlashStringHelper* message) {
+ int ret = 0;
+ if (this_ret == WOLFSSL_SUCCESS) {
+ Serial.print(F("Success: "));
+ Serial.println(message);
+ }
+ else {
+ Serial.print(F("ERROR: return = "));
+ Serial.print(this_ret);
+ Serial.print(F(": "));
+ Serial.println(message);
+ Serial.println(wc_GetErrorString(this_ret));
+ if (halt_on_error) {
+ fail_wait();
+ }
+ }
+ show_memory();
+
+ return ret;
+} /* error_check */
+
+/*****************************************************************************/
+/* wolfSSL error_check_ssl */
+/* Parameters: */
+/* ssl is the current WOLFSSL object pointer */
+/* halt_on_error set to true to suspend operations for critical error */
+/* message is expected to be a memory-efficient F("") macro string */
+/*****************************************************************************/
+int error_check_ssl(WOLFSSL* ssl, int this_ret, bool halt_on_error,
+ const __FlashStringHelper* message) {
+ int err = 0;
+
+ if (ssl == NULL) {
+ Serial.println(F("ssl is Null; Unable to allocate SSL object?"));
+#ifndef DEBUG_WOLFSSL
+ Serial.println(F("Define DEBUG_WOLFSSL in user_settings.h for more."));
+#else
+ Serial.println(F("See wolfssl/wolfcrypt/error-crypt.h for codes."));
+#endif
+ Serial.print(F("ERROR: "));
+ Serial.println(message);
+ show_memory();
+ if (halt_on_error) {
+ fail_wait();
+ }
+ }
+ else {
+ err = wolfSSL_get_error(ssl, this_ret);
+ if (err == WOLFSSL_SUCCESS) {
+ Serial.print(F("Success m: "));
+ Serial.println(message);
+ }
+ else {
+ if (err < 0) {
+ wolfSSL_ERR_error_string(err, errBuf);
+ Serial.print(F("WOLFSSL Error: "));
+ Serial.print(err);
+ Serial.print(F("; "));
+ Serial.println(errBuf);
+ }
+ else {
+ Serial.println(F("Success: ssl object."));
+ }
+ }
+ }
+
+ return err;
+} /* error_check_ssl */
+
+/*****************************************************************************/
+/*****************************************************************************/
+/* Arduino loop() */
+/*****************************************************************************/
+/*****************************************************************************/
+void loop()
+{
+ /* standard variables used in a dtls client */
+ char sendLine[MAXLINE] = "Hello DTLS wolfSSL!";
+ char recvLine[MAXLINE - 1];
+ struct sockaddr_in servAddr;
+ const char* cipherName;
+ int msg_ct = 0;
+ int n = 0;
+ int sockfd = INVALID_SOCKET;
+ int err;
+ int ret;
+ int exitVal = 1;
+
+ /* Assign ssl variable */
+ ssl = wolfSSL_new(ctx);
+ if (ssl == NULL) {
+ Serial.println(F("unable to get ssl object\n"));
+ goto cleanup;
+ }
+
+ /* servAddr setup */
+ memset(&servAddr, 0, sizeof(servAddr));
+ servAddr.sin_family = AF_INET;
+ servAddr.sin_port = htons(WOLFSSL_PORT);
+ if (inet_pton(AF_INET, WOLFSSL_DTLS_SERVER_HOST, &servAddr.sin_addr) < 1) {
+ perror("inet_pton()");
+ goto cleanup;
+ }
+
+ if (wolfSSL_dtls_set_peer(ssl, &servAddr, sizeof(servAddr))
+ != WOLFSSL_SUCCESS) {
+ Serial.println(F("wolfSSL_dtls_set_peer failed\n"));
+ goto cleanup;
+ }
+
+ if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
+ perror("socket()");
+ goto cleanup;
+ }
+
+ /* Set the file descriptor for ssl */
+ if (wolfSSL_set_fd(ssl, sockfd) != WOLFSSL_SUCCESS) {
+ Serial.println(F("cannot set socket file descriptor\n"));
+ goto cleanup;
+ }
+
+ Serial.print(F("Connecting to wolfSSL DTLS Secure Server..."));
+ do {
+ reconnect--;
+ err = 0; /* reset error */
+ Serial.println(F("wolfSSL_connect ..."));
+ ret = wolfSSL_connect(ssl);
+ if ((ret != WOLFSSL_SUCCESS) && (ret != WC_PENDING_E)) {
+ Serial.println(F("Failed connection, checking error."));
+ err = error_check_ssl(ssl, ret, true,
+ F("Create WOLFSSL object from ctx"));
+ Serial.print("err =");
+ Serial.println(err);
+ }
+ else {
+ Serial.print(PROGRESS_DOT);
+ }
+ } while ((err == WC_PENDING_E) && (reconnect > 0));
+
+ Serial.println();
+ Serial.println(F("Connected!"));
+ Serial.print(F("SSL version is "));
+ Serial.println(wolfSSL_get_version(ssl));
+
+ cipherName = wolfSSL_get_cipher(ssl);
+ Serial.print(F("SSL cipher suite is "));
+ Serial.println(cipherName);
+
+/*****************************************************************************/
+/* Code for sending datagram to server */
+/*****************************************************************************/
+ Serial.println(F("Begin DTLS Loop..."));
+ msg_ct = 0;
+ while (msg_ct < DTLS_MESSAGE_CT || (DTLS_MESSAGE_CT == -1)) {
+ msg_ct++;
+
+ /* Send sendLine to the server */
+ Serial.print(F("Sending Message #"));
+ Serial.print(msg_ct);
+ Serial.print(F(": \""));
+ Serial.print(F(sendLine));
+ Serial.println(F("\" ... "));
+ if (wolfSSL_write(ssl, sendLine, strlen(sendLine)) != strlen(sendLine)) {
+ err = error_check_ssl(ssl, ret, true,
+ F("Create WOLFSSL object from ctx"));
+ Serial.print("err =");
+ Serial.println(err);
+ goto cleanup;
+ }
+
+ /* n is the # of bytes received */
+ Serial.println(F("Reading Message..."));
+ n = wolfSSL_read(ssl, recvLine, sizeof(recvLine)-1);
+
+ if (n > 0) {
+ /* Add a terminating character to the generic server message */
+ recvLine[n] = '\0';
+ Serial.println(F("Got Message..."));
+ printf("%s\n", recvLine);
+ }
+ else {
+ err = error_check_ssl(ssl, ret, true,
+ F("Create WOLFSSL object from ctx"));
+ Serial.print("err =");
+ Serial.println(err);
+ goto cleanup;
+ }
+
+ } /* (msg_ct > DTLS_MESSAGE_CT || (DTLS_MESSAGE_CT == -1)) */
+
+ exitVal = 0;
+cleanup:
+ if (ssl != NULL) {
+ /* Attempt a full shutdown */
+ ret = wolfSSL_shutdown(ssl);
+ if (ret == WOLFSSL_SHUTDOWN_NOT_DONE) {
+ Serial.println("Not done... Try again wolfSSL_shutdown");
+ ret = wolfSSL_shutdown(ssl);
+ }
+
+ if (ret != WOLFSSL_SUCCESS) {
+ err = error_check_ssl(ssl, ret, true,
+ F("Create WOLFSSL object from ctx"));
+ Serial.print("err =");
+ Serial.println(err);
+ Serial.println(F("wolfSSL_shutdown failed\n"));
+ }
+ wolfSSL_free(ssl);
+ }
+ if (sockfd != INVALID_SOCKET) {
+ close(sockfd);
+ }
+ if (ctx != NULL) {
+ wolfSSL_CTX_free(ctx);
+ }
+ wolfSSL_Cleanup();
+
+ Serial.print(F("Reset to start over."));
+ Serial.print(F("Done!"));
+
+ while (1) {
+ delay(1000);
+ }
+} /* Arduino loop */
+
diff --git a/Arduino/sketches/wolfssl_server/wolfssl_server.ino b/Arduino/sketches/wolfssl_server/wolfssl_server.ino
index 1b9d4ede..7f75bcc7 100644
--- a/Arduino/sketches/wolfssl_server/wolfssl_server.ino
+++ b/Arduino/sketches/wolfssl_server/wolfssl_server.ino
@@ -6,7 +6,7 @@
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
@@ -39,6 +39,18 @@ Tested with:
/* If you have a private include, define it here, otherwise edit WiFi params */
/* #define MY_PRIVATE_CONFIG "/workspace/my_private_config.h" */
+#if defined(ARDUINO) && defined(ESP8266)
+ #warning "This example is not yet supported on Arduino ESP8266"
+#endif
+
+#if defined(DEBUG_WOLFSSL)
+ /* Optionally enabled verbose wolfSSL debugging */
+ #define DEBUG_WOLFSSL_MESSAGES_ON
+#else
+ /* DEBUG_WOLFSSL needs to be enabled */
+ #undef DEBUG_WOLFSSL_MESSAGES_ON
+#endif
+
/* set REPEAT_CONNECTION to a non-zero value to continually run the example. */
#define REPEAT_CONNECTION 1
@@ -68,12 +80,12 @@ Tested with:
/* the /workspace directory may contain a private config
* excluded from GitHub with items such as WiFi passwords */
#include MY_PRIVATE_CONFIG
- static const char ssid[] PROGMEM = MY_ARDUINO_WIFI_SSID;
- static const char password[] PROGMEM = MY_ARDUINO_WIFI_PASSWORD;
+ static const char ssid[] PROGMEM = MY_ARDUINO_WIFI_SSID;
+ static const char password[] PROGMEM = MY_ARDUINO_WIFI_PASSWORD;
#else
/* when using WiFi capable boards: */
- static const char ssid[] PROGMEM = "your_SSID";
- static const char password[] PROGMEM = "your_PASSWORD";
+ static const char ssid[] PROGMEM = "your_SSID";
+ static const char password[] PROGMEM = "your_PASSWORD";
#endif
#define BROADCAST_ADDRESS "255.255.255.255"
@@ -132,6 +144,10 @@ Tested with:
#elif defined(ESP8266)
#define USING_WIFI
#include
+ /* Ensure the F() flash macro is defined */
+ #ifndef F
+ #define F
+ #endif
WiFiClient client;
WiFiServer server(WOLFSSL_PORT);
#elif defined(ARDUINO_SAM_DUE)
@@ -140,7 +156,12 @@ Tested with:
/* Needs "Ethernet by Various" library to be installed. Tested with V2.0.2 */
#include
EthernetClient client;
- EthernetClient server(WOLFSSL_PORT);
+ EthernetServer server(WOLFSSL_PORT);
+#elif defined(ARDUINO_AVR_ETHERNET) || defined(ARDUINO_AVR_LEONARDO_ETH)
+ /* Boards such as arduino:avr:ethernet and arduino:avr:leonardoeth */
+ #include
+ EthernetClient client;
+ EthernetServer server(WOLFSSL_PORT);
#elif defined(ARDUINO_SAMD_NANO_33_IOT)
#define USING_WIFI
#include
@@ -153,6 +174,36 @@ Tested with:
#include
WiFiClient client;
WiFiServer server(WOLFSSL_PORT);
+#elif defined(ARDUINO_SAMD_TIAN)
+ #include
+ #include
+ HttpClient client;
+ /* Arduino Tian does not support network shields like the standard Ethernet or Wi-Fi shields. */
+ #error "HttpClient cannot be used for this example"
+#elif defined(ARDUINO_PORTENTA_X8)
+ /* The Portenta is a Linux device. See wolfSSL examples:
+ * https://github.com/wolfSSL/wolfssl/tree/master/examples
+ * By default Serial is disabled and mapped to ErrorSerial */
+ #include
+
+ /* ----No - network placeholders(compile - only) ---- */
+ #include
+ struct X8NoNetClient {
+ int write(const uint8_t*, size_t) { return -1; }
+ int available() { return 0; }
+ int read() { return -1; }
+ void stop() {}
+ bool connected() { return false; }
+ IPAddress remoteIP() { return IPAddress(0, 0, 0, 0); }
+ };
+ struct X8NoNetServer {
+ explicit X8NoNetServer(uint16_t) {}
+ void begin() {}
+ X8NoNetClient available() { return X8NoNetClient(); }
+ };
+
+ X8NoNetClient client;
+ X8NoNetServer server(WOLFSSL_PORT);
#elif defined(USING_WIFI)
#define USING_WIFI
#include
@@ -206,7 +257,10 @@ static char errBuf[80];
static int EthernetSend(WOLFSSL* ssl, char* msg, int sz, void* ctx);
static int EthernetReceive(WOLFSSL* ssl, char* reply, int sz, void* ctx);
static int reconnect = RECONNECT_ATTEMPTS;
+#if 0
+/* optional showPeerEx, currently disabled */
static int lng_index PROGMEM = 0; /* 0 = English */
+#endif
#if defined(__arm__)
#include
@@ -463,7 +517,8 @@ int setup_network(void) {
/*****************************************************************************/
/* Arduino setup_wolfssl() */
/*****************************************************************************/
-int setup_wolfssl(void) {
+int setup_wolfssl(void)
+{
int ret = 0;
WOLFSSL_METHOD* method;
@@ -483,8 +538,14 @@ int setup_wolfssl(void) {
#endif
#if defined(DEBUG_WOLFSSL)
- wolfSSL_Debugging_ON();
- Serial.println(F("wolfSSL Debugging is On!"));
+ Serial.println(F("wolfSSL Debugging is available! (DEBUG_WOLFSSL)"));
+ #if defined(DEBUG_WOLFSSL_MESSAGES_ON)
+ Serial.println(F("Enabling verbose messages wolfSSL_Debugging_ON"));
+ wolfSSL_Debugging_ON();
+ #else
+ Serial.println(F("Enable verbose messages with wolfSSL_Debugging_ON"));
+ Serial.println(F("or define DEBUG_WOLFSSL_MESSAGES_ON"));
+ #endif
#else
Serial.println(F("wolfSSL Debugging is Off! (enable with DEBUG_WOLFSSL)"));
#endif
@@ -510,6 +571,7 @@ int setup_wolfssl(void) {
* It is best on embedded devices to choose a TLS session cache size. */
#endif
+ /* Initialize wolfSSL before assigning ctx */
ret = wolfSSL_Init();
if (ret == WOLFSSL_SUCCESS) {
Serial.println("Successfully called wolfSSL_Init");
@@ -544,7 +606,8 @@ int setup_wolfssl(void) {
/*****************************************************************************/
/* Arduino setup_certificates() */
/*****************************************************************************/
-int setup_certificates(void) {
+int setup_certificates(void)
+{
int ret = 0;
Serial.println(F("Initializing certificates..."));
@@ -594,7 +657,8 @@ int setup_certificates(void) {
/* Arduino setup() */
/*****************************************************************************/
/*****************************************************************************/
-void setup(void) {
+void setup(void)
+{
int i = 0;
Serial.begin(SERIAL_BAUD);
while (!Serial && (i < 10)) {
@@ -725,7 +789,7 @@ int error_check_ssl(WOLFSSL* ssl, int this_ret, bool halt_on_error,
}
return err;
-}
+} /* error_check_ssl */
/*****************************************************************************/
/*****************************************************************************/
diff --git a/Arduino/sketches/wolfssl_server_dtls/README.md b/Arduino/sketches/wolfssl_server_dtls/README.md
new file mode 100644
index 00000000..43deb7ec
--- /dev/null
+++ b/Arduino/sketches/wolfssl_server_dtls/README.md
@@ -0,0 +1,140 @@
+# Arduino Basic TLS Server
+
+Open the [wolfssl_server_dtls.ino](./wolfssl_server_dtls.ino) file in the Arduino IDE.
+
+If using WiFi, be sure to set `ssid` and `password` values.
+
+May need "Ethernet by Various" library to be installed. Tested with v2.0.2 and v2.8.1.
+
+See the `#define WOLFSSL_TLS_SERVER_HOST` to set your own server address.
+
+Other IDE products are also supported, such as:
+
+- [PlatformIO in VS Code](https://docs.platformio.org/en/latest/frameworks/arduino.html)
+- [VisualGDB](https://visualgdb.com/tutorials/arduino/)
+- [VisualMicro](https://www.visualmicro.com/)
+
+For examples on other platforms, see the [IDE directory](https://github.com/wolfssl/wolfssl/tree/master/IDE).
+Additional examples can be found on [wolfSSL/wolfssl-examples](https://github.com/wolfSSL/wolfssl-examples/).
+
+## Connect with an Arduino Sketch
+
+See the companion [Arduino Sketch Client](../wolfssl_client/wolfssl_client_dtls.ino).
+
+## Connect with Linux Client
+
+See also the [wolfSSL Example TLS Client](https://github.com/wolfSSL/wolfssl/tree/master/examples/client)
+and [wolfSSL Example TLS Server](https://github.com/wolfSSL/wolfssl/tree/master/examples/server).
+
+Assuming a listening [Arduino Sketch Server](./wolfssl_server.ino) at `192.168.1.38` on port `11111`,
+connect with the `client` executable:
+
+```
+./examples/client/client -h 192.168.1.38 -p 11111 -v 3
+```
+
+## wolfSSL Error -308 wolfSSL_connect error state on socket
+
+When using a wired Ethernet connection, and this error is encountered, simply
+press the reset button or power cycle the Arduino before making a connection.
+
+Here's one possible script to test the server from a command-line client:
+
+```bash
+#!/usr/bin/env bash
+echo "client log " > client_log.txt
+counter=1
+THIS_ERR=0
+while [ $THIS_ERR -eq 0 ]; do
+ ./examples/client/client -h 192.168.1.38 -p 11111 -v 3 >> client_log.txt
+
+ THIS_ERR=$?
+ if [ $? -ne 0 ]; then
+ echo "Failed!"
+ exit 1
+ fi
+ echo "Iteration $counter"
+ echo "Iteration $counter" >> client_log.txt
+ ((counter++))
+done
+```
+
+Output expected from the `client` command:
+
+```
+$ ./examples/client/client -h 192.168.1.38 -p 11111 -v 3
+Alternate cert chain used
+ issuer : /C=US/ST=Montana/L=Bozeman/O=Sawtooth/OU=Consulting/CN=www.wolfssl.com/emailAddress=info@wolfssl.com
+ subject: /C=US/ST=Montana/L=Bozeman/O=wolfSSL/OU=Support/CN=www.wolfssl.com/emailAddress=info@wolfssl.com
+ altname = example.com
+ altname = 127.0.0.1
+ serial number:01
+SSL version is TLSv1.2
+SSL cipher suite is ECDHE-RSA-AES128-GCM-SHA256
+SSL curve name is SECP256R1
+---
+Server certificate
+-----BEGIN CERTIFICATE-----
+MIIE6DCCA9CgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBlDELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xETAPBgNVBAoMCFNh
+d3Rvb3RoMRMwEQYDVQQLDApDb25zdWx0aW5nMRgwFgYDVQQDDA93d3cud29sZnNz
+bC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjMxMjEz
+MjIxOTI4WhcNMjYwOTA4MjIxOTI4WjCBkDELMAkGA1UEBhMCVVMxEDAOBgNVBAgM
+B01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xEDAOBgNVBAoMB3dvbGZTU0wxEDAO
+BgNVBAsMB1N1cHBvcnQxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqG
+SIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAMCVCOFXQfJxbbfSRUEnAWXGRa7yvCQwuJXOL07W9hyIvHyf+6hn
+f/5cnFF194rKB+c1L4/hvXvAL3yrZKgX/Mpde7rgIeVyLm8uhtiVc9qsG1O5Xz/X
+GQ0lT+FjY1GLC2Q/rUO4pRxcNLOuAKBjxfZ/C1loeHOmjBipAm2vwxkBLrgQ48bM
+QLRpo0YzaYduxLsXpvPo3a1zvHsvIbX9ZlEMvVSz4W1fHLwjc9EJA4kU0hC5ZMMq
+0KGWSrzh1Bpbx6DAwWN4D0Q3MDKWgDIjlaF3uhPSl3PiXSXJag3DOWCktLBpQkIJ
+6dgIvDMgs1gip6rrxOHmYYPF0pbf2dBPrdcCAwEAAaOCAUUwggFBMB0GA1UdDgQW
+BBSzETLJkpiE4sn40DtuA0LKHw6OPDCB1AYDVR0jBIHMMIHJgBQnjmcRdMMmHT/t
+M2OzpNgdMOXo1aGBmqSBlzCBlDELMAkGA1UEBhMCVVMxEDAOBgNVBAgMB01vbnRh
+bmExEDAOBgNVBAcMB0JvemVtYW4xETAPBgNVBAoMCFNhd3Rvb3RoMRMwEQYDVQQL
+DApDb25zdWx0aW5nMRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG
+9w0BCQEWEGluZm9Ad29sZnNzbC5jb22CFDNEGqhsAez2YPJwUQpM0RT6vOlEMAwG
+A1UdEwQFMAMBAf8wHAYDVR0RBBUwE4ILZXhhbXBsZS5jb22HBH8AAAEwHQYDVR0l
+BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBK/7nl
+hZvaU2Z/ByK/thnqQuukEQdi/zlfMzc6hyZxPROyyrhkOHuKmUgOpaRrsZlu4EZR
+vRlSrbymfip6fCOnzNteQ31rBMi33ZWt8JGAWcUZkSYnkbhIHOtVtqp9pDjxA7xs
+i6qU1jwFepbFBvEmFC51+93lNbMBLLOtYlohmgi+Vvz5okKHhuWpxZnPrhS+4LkI
+JA0dXNYU4UyfQLOp6S1Si0y/rEQxZ8GNBoXsD+SZ10t7IQZm1OT1nf+O8IY5WB2k
+W+Jj73zJGIeoAiUQPoco+fXvR56lgAgRkGj+0aOoUbk3/9XKfId/a7wsEsjFhYv8
+DMa5hrjJBMNRN9JP
+-----END CERTIFICATE-----
+Session timeout set to 500 seconds
+Client Random : 56A0BB9647B064D3F20947032B74B31FDB4C93DBAC9460BA8AEA213A2B2DD4A8
+SSL-Session:
+ Protocol : TLSv1.2
+ Cipher : TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+ Session-ID: 3255404E997FA9C27ECB4F1A20A70E722E4AA504B63A945FC175434D1907EC31
+ Session-ID-ctx:
+ Master-Key: 67F22168BBADD678643BBA76B398277270C29788AC18FD05B57F6B715F49A7BCEEF75BEAF7FE266B0CC058534AF76C1F
+ TLS session ticket: NONE
+ Start Time: 1705533296
+ Timeout : 500 (sec)
+ Extended master secret: no
+I hear you fa shizzle!
+```
+
+### Troubleshooting
+
+When encountering odd errors such as `undefined reference to ``_impure_ptr'`, such as this:
+
+```text
+c:/users/gojimmypi/appdata/local/arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/esp-2021r2-patch5-8.4.0/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: C:\Users\gojimmypi\AppData\Local\Temp\arduino\sketches\EAB8D79A02D1ECF107884802D893914E\libraries\wolfSSL\wolfcrypt\src\logging.c.o:(.literal.wolfssl_log+0x8): undefined reference to `_impure_ptr'
+collect2.exe: error: ld returned 1 exit status
+
+exit status 1
+
+Compilation error: exit status 1
+```
+
+Try cleaning the Arduino cache directories. For Windows, that's typically in:
+
+```text
+C:\Users\%USERNAME%\AppData\Local\Temp\arduino\sketches
+```
+
+Remove all other boards from other serial ports, leaving one the one being programmed.
diff --git a/Arduino/sketches/wolfssl_server_dtls/wolfssl_server_dtls.ino b/Arduino/sketches/wolfssl_server_dtls/wolfssl_server_dtls.ino
new file mode 100644
index 00000000..38e9148f
--- /dev/null
+++ b/Arduino/sketches/wolfssl_server_dtls/wolfssl_server_dtls.ino
@@ -0,0 +1,984 @@
+/* server-dtls13.c
+ *
+ * Copyright (C) 2006-2025 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ *
+ *=============================================================================
+ *
+ * Bare-bones example of a DTLS 1.3 server for instructional/learning purposes.
+ * This example can only accept one connection at a time.
+ *
+ * Define USE_DTLS12 to use DTLS 1.2 instead of DTLS 1.3
+/*
+Tested with:
+
+1) Intel Galileo acting as the Client, with a laptop acting as a server using
+ the server example provided in examples/server.
+ Legacy Arduino v1.86 was used to compile and program the Galileo
+
+2) Espressif ESP32 WiFi
+
+3) Arduino Due, Nano33 IoT, Nano RP-2040
+*/
+
+/*
+ * Note to code editors: the Arduino client and server examples are edited in
+ * parallel for side-by-side comparison between examples.
+ */
+
+/* If you have a private include, define it here, otherwise edit WiFi params */
+/* #define MY_PRIVATE_CONFIG "/workspace/my_private_config.h" */
+
+#if defined(ARDUINO) && defined(ESP8266)
+ #warning "This example is not yet supported on Arduino ESP8266"
+#endif
+
+#if defined(DEBUG_WOLFSSL)
+ /* Optionally enabled verbose wolfSSL debugging */
+ #define DEBUG_WOLFSSL_MESSAGES_ON
+#else
+ /* DEBUG_WOLFSSL needs to be enabled */
+ #undef DEBUG_WOLFSSL_MESSAGES_ON
+#endif
+
+/* set REPEAT_CONNECTION to a non-zero value to continually run the example. */
+#define REPEAT_CONNECTION 0
+
+/* Edit this with your other TLS host server address to connect to: */
+/* #define WOLFSSL_TLS_SERVER_HOST "192.168.1.39" */
+
+/* wolfssl TLS examples communicate on port 11111 */
+#define WOLFSSL_PORT 11111
+
+/* Choose a monitor serial baud rate: 9600, 14400, 19200, 57600, 74880, etc. */
+#define SERIAL_BAUD 115200
+
+/* We'll wait up to 2000 milliseconds to properly shut down connection */
+#define SHUTDOWN_DELAY_MS 2000
+
+/* Number of times to retry connection. */
+#define RECONNECT_ATTEMPTS 20
+
+/* Assume bad socket until proven otherwise */
+#define INVALID_SOCKET -1
+
+/* Maximum size in bytes of buffer to send and receive */
+#define MAXLINE 128
+
+/* Optional stress test. Define to consume memory until exhausted: */
+/* #define MEMORY_STRESS_TEST */
+
+/* Choose client or server example, not both. */
+/* #define WOLFSSL_CLIENT_EXAMPLE */
+#define WOLFSSL_SERVER_EXAMPLE
+
+#if defined(MY_PRIVATE_CONFIG)
+ /* the /workspace directory may contain a private config
+ * excluded from GitHub with items such as WiFi passwords */
+ #include MY_PRIVATE_CONFIG
+ static const char ssid[] PROGMEM = MY_ARDUINO_WIFI_SSID;
+ static const char password[] PROGMEM = MY_ARDUINO_WIFI_PASSWORD;
+#else
+ /* when using WiFi capable boards: */
+ static const char ssid[] PROGMEM = "your_SSID";
+ static const char password[] PROGMEM = "your_PASSWORD";
+#endif
+
+#define BROADCAST_ADDRESS "255.255.255.255"
+
+/* There's an optional 3rd party NTPClient library by Fabrice Weinberg.
+ * If it is installed, uncomment define USE_NTP_LIB here: */
+/* #define USE_NTP_LIB */
+#ifdef USE_NTP_LIB
+ #include
+#endif
+
+/* wolfSSL user_settings.h must be included from settings.h
+ * Make all configurations changes in user_settings.h
+ * Do not edit wolfSSL `settings.h` or `config.h` files.
+ * Do not explicitly include user_settings.h in any source code.
+ * Each Arduino sketch that uses wolfSSL must have: #include "wolfssl.h"
+ * C/C++ source files can use: #include
+ * The wolfSSL "settings.h" must be included in each source file using wolfSSL.
+ * The wolfSSL "settings.h" must appear before any other wolfSSL include.
+ */
+#include
+/* Important: make sure settings.h appears before any other wolfSSL headers */
+#include
+/* Reminder: settings.h includes user_settings.h
+ * For ALL project wolfSSL settings, see:
+ * [your path]/Arduino\libraries\wolfSSL\src\user_settings.h */
+#include
+#include
+#include
+
+#ifndef WOLFSSL_DTLS
+ /* Support for DTLS by default was added after wolfSSL v5.8.2 release */
+ #error "This example requires WOLFSSL_DTLS. See user_settings.h in the Arduino wolfssl library"
+#endif
+
+/* Define DEBUG_WOLFSSL in user_settings.h for more verbose logging. */
+#if defined(DEBUG_WOLFSSL)
+ #define PROGRESS_DOT F("")
+#else
+ #define PROGRESS_DOT F(".")
+#endif
+
+/* Convert a macro to a string */
+#define xstr(x) str(x)
+#define str(x) #x
+
+/* optional board-specific networking includes */
+#if defined(ESP32)
+ #define USING_WIFI
+ #include
+ #include
+ #ifdef USE_NTP_LIB
+ WiFiUDP ntpUDP;
+ #endif
+ /* Ensure the F() flash macro is defined */
+ #ifndef F
+ #define F
+ #endif
+ WiFiClient client;
+ WiFiServer server(WOLFSSL_PORT);
+#elif defined(ESP8266)
+ #define USING_WIFI
+ #include
+ /* Ensure the F() flash macro is defined */
+ #ifndef F
+ #define F
+ #endif
+ WiFiClient client;
+ WiFiServer server(WOLFSSL_PORT);
+#elif defined(ARDUINO_SAM_DUE)
+ #include
+ /* There's no WiFi/Ethernet on the Due. Requires Ethernet Shield.
+ /* Needs "Ethernet by Various" library to be installed. Tested with V2.0.2 */
+ #include
+ EthernetClient client;
+ EthernetClient server(WOLFSSL_PORT);
+#elif defined(ARDUINO_AVR_ETHERNET) || defined(ARDUINO_AVR_LEONARDO_ETH)
+ /* Boards such as arduino:avr:ethernet and arduino:avr:leonardoeth */
+ #include
+ EthernetClient client;
+
+ EthernetClient server(WOLFSSL_PORT);
+#elif defined(ARDUINO_SAMD_NANO_33_IOT)
+ #define USING_WIFI
+ #include
+ #include /* Needs Arduino WiFiNINA library installed manually */
+ WiFiClient client;
+ WiFiServer server(WOLFSSL_PORT);
+#elif defined(ARDUINO_ARCH_RP2040)
+ #define USING_WIFI
+ #include
+ #include
+ WiFiClient client;
+ WiFiServer server(WOLFSSL_PORT);
+#elif defined(ARDUINO_SAMD_TIAN)
+ #include
+ #include
+ HttpClient client;
+ /* Arduino Tian does not support network shields like the standard Ethernet or Wi-Fi shields. */
+ #error "HttpClient cannot be used for this example"
+#elif defined(ARDUINO_PORTENTA_X8)
+ /* The Portenta is a Linux device. See wolfSSL examples:
+ * https://github.com/wolfSSL/wolfssl/tree/master/examples
+ * By default Serial is disabled and mapped to ErrorSerial */
+ #include
+
+ /* ----No - network placeholders(compile - only) ---- */
+ #include
+ struct X8NoNetClient {
+ int write(const uint8_t*, size_t) { return -1; }
+ int available() { return 0; }
+ int read() { return -1; }
+ void stop() {}
+ bool connected() { return false; }
+ IPAddress remoteIP() { return IPAddress(0, 0, 0, 0); }
+ };
+ struct X8NoNetServer {
+ explicit X8NoNetServer(uint16_t) {}
+ void begin() {}
+ X8NoNetClient available() { return X8NoNetClient(); }
+ };
+
+ X8NoNetClient client;
+ X8NoNetServer server(WOLFSSL_PORT);
+#elif defined(USING_WIFI)
+ #define USING_WIFI
+ #include
+ #include
+ #ifdef USE_NTP_LIB
+ WiFiUDP ntpUDP;
+ #endif
+ WiFiClient client;
+ WiFiServer server(WOLFSSL_PORT);
+/* TODO
+#elif defined(OTHER_BOARD)
+*/
+#else
+ /* assume all other boards using WiFi library. Edit as needed: */
+ #include
+ #define USING_WIFI
+ WiFiClient client;
+ WiFiServer server(WOLFSSL_PORT);
+#endif
+
+/* Only for syntax highlighters to show interesting options enabled: */
+#if defined(HAVE_SNI) \
+ || defined(HAVE_MAX_FRAGMENT) \
+ || defined(HAVE_TRUSTED_CA) \
+ || defined(HAVE_TRUNCATED_HMAC) \
+ || defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
+ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) \
+ || defined(HAVE_SUPPORTED_CURVES) \
+ || defined(HAVE_ALPN) \
+ || defined(HAVE_SESSION_TICKET) \
+ || defined(HAVE_SECURE_RENEGOTIATION) \
+ || defined(HAVE_SERVER_RENEGOTIATION_INFO)
+#endif
+
+static const int port PROGMEM = WOLFSSL_PORT; /* port on server to connect to */
+
+static WOLFSSL_CTX* ctx = NULL;
+static WOLFSSL* ssl = NULL;
+static char* wc_error_message = (char*)malloc(80 + 1);
+static char errBuf[80];
+
+#if defined(MEMORY_STRESS_TEST)
+ #define MEMORY_STRESS_ITERATIONS 100
+ #define MEMORY_STRESS_BLOCK_SIZE 1024
+ #define MEMORY_STRESS_INITIAL (4*1024)
+ static char* memory_stress[MEMORY_STRESS_ITERATIONS]; /* typically 1K per item */
+ static int mem_ctr = 0;
+#endif
+
+static int EthernetSend(WOLFSSL* ssl, char* msg, int sz, void* ctx);
+static int EthernetReceive(WOLFSSL* ssl, char* reply, int sz, void* ctx);
+static int reconnect = RECONNECT_ATTEMPTS;
+#if 0
+/* optional showPeerEx, currently disabled */
+static int lng_index PROGMEM = 0; /* 0 = English */
+#endif
+static int listenfd = INVALID_SOCKET; /* Initialize our socket */
+
+#if defined(__arm__)
+ #include
+ extern char _end;
+ extern "C" char *sbrk(int i);
+ static char *ramstart=(char *)0x20070000;
+ static char *ramend=(char *)0x20088000;
+#endif
+
+/*****************************************************************************/
+/* fail_wait - in case of unrecoverable error */
+/*****************************************************************************/
+int fail_wait(void) {
+ show_memory();
+
+ Serial.println(F("Failed. Halt."));
+ while (1) {
+ delay(1000);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+/* show_memory() to optionally view during debugging. */
+/*****************************************************************************/
+int show_memory(void)
+{
+#if defined(__arm__)
+ struct mallinfo mi = mallinfo();
+
+ char *heapend=sbrk(0);
+ register char * stack_ptr asm("sp");
+ #if defined(DEBUG_WOLFSSL_VERBOSE)
+ Serial.print(" arena=");
+ Serial.println(mi.arena);
+ Serial.print(" ordblks=");
+ Serial.println(mi.ordblks);
+ Serial.print(" uordblks=");
+ Serial.println(mi.uordblks);
+ Serial.print(" fordblks=");
+ Serial.println(mi.fordblks);
+ Serial.print(" keepcost=");
+ Serial.println(mi.keepcost);
+ #endif
+
+ #if defined(DEBUG_WOLFSSL) || defined(MEMORY_STRESS_TEST)
+ Serial.print("Estimated free memory: ");
+ Serial.print(stack_ptr - heapend + mi.fordblks);
+ Serial.println(F(" bytes"));
+ #endif
+
+ #if (0)
+ /* Experimental: not supported on all devices: */
+ Serial.print("RAM Start %lx\n", (unsigned long)ramstart);
+ Serial.print("Data/Bss end %lx\n", (unsigned long)&_end);
+ Serial.print("Heap End %lx\n", (unsigned long)heapend);
+ Serial.print("Stack Ptr %lx\n",(unsigned long)stack_ptr);
+ Serial.print("RAM End %lx\n", (unsigned long)ramend);
+
+ Serial.print("Heap RAM Used: ",mi.uordblks);
+ Serial.print("Program RAM Used ",&_end - ramstart);
+ Serial.print("Stack RAM Used ",ramend - stack_ptr);
+
+ Serial.print("Estimated Free RAM: %d\n\n",stack_ptr - heapend + mi.fordblks);
+ #endif
+#else
+ Serial.println(F("show_memory() not implemented for this platform"));
+#endif
+ return 0;
+}
+
+/*****************************************************************************/
+/* Arduino setup_hardware() */
+/*****************************************************************************/
+int setup_hardware(void) {
+ int ret = 0;
+
+#if defined(ARDUINO_SAMD_NANO_33_IOT)
+ Serial.println(F("Detected known tested and working Arduino Nano 33 IoT"));
+#elif defined(ARDUINO_ARCH_RP2040)
+ Serial.println(F("Detected known tested and working Arduino RP-2040"));
+#elif defined(__arm__) && defined(ID_TRNG) && defined(TRNG)
+ /* need to manually turn on random number generator on Arduino Due, etc. */
+ pmc_enable_periph_clk(ID_TRNG);
+ trng_enable(TRNG);
+ Serial.println(F("Enabled ARM TRNG"));
+#endif
+
+ show_memory();
+ randomSeed(analogRead(0));
+ return ret;
+}
+
+/*****************************************************************************/
+/* Arduino setup_datetime() */
+/* The device needs to have a valid date within the valid range of certs. */
+/*****************************************************************************/
+int setup_datetime(void) {
+ int ret = 0;
+ int ntp_tries = 20;
+
+ /* we need a date in the range of cert expiration */
+#ifdef USE_NTP_LIB
+ #if defined(ESP32)
+ NTPClient timeClient(ntpUDP, "pool.ntp.org");
+
+ timeClient.begin();
+ timeClient.update();
+ delay(1000);
+ while (!timeClient.isTimeSet() && (ntp_tries > 0)) {
+ timeClient.forceUpdate();
+ Serial.println(F("Waiting for NTP update"));
+ delay(2000);
+ ntp_tries--;
+ }
+ if (ntp_tries <= 0) {
+ Serial.println(F("Warning: gave up waiting on NTP"));
+ }
+ Serial.println(timeClient.getFormattedTime());
+ Serial.println(timeClient.getEpochTime());
+ #endif
+#endif
+
+#if defined(ESP32)
+ /* see esp32-hal-time.c */
+ ntp_tries = 5;
+ /* Replace "pool.ntp.org" with your preferred NTP server */
+ configTime(0, 0, "pool.ntp.org");
+
+ /* Wait for time to be set */
+ while ((time(nullptr) <= 100000) && ntp_tries > 0) {
+ Serial.println(F("Waiting for time to be set..."));
+ delay(2000);
+ ntp_tries--;
+ }
+#endif
+
+ return ret;
+} /* setup_datetime */
+
+/*****************************************************************************/
+/* Arduino setup_network() */
+/*****************************************************************************/
+int setup_network(void) {
+ int ret = 0;
+
+#if defined(USING_WIFI)
+ int status = WL_IDLE_STATUS;
+
+ /* The ESP8266 & ESP32 support both AP and STA. We'll use STA: */
+ #if defined(ESP8266) || defined(ESP32)
+ WiFi.mode(WIFI_STA);
+ #else
+ String fv;
+ if (WiFi.status() == WL_NO_MODULE) {
+ Serial.println("Communication with WiFi module failed!");
+ /* don't continue if no network */
+ while (true) ;
+ }
+
+ fv = WiFi.firmwareVersion();
+ if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
+ Serial.println("Please upgrade the firmware");
+ }
+ #endif
+
+ Serial.print(F("Connecting to WiFi "));
+ Serial.print(ssid);
+ status = WiFi.begin(ssid, password);
+ while (status != WL_CONNECTED) {
+ delay(1000);
+ Serial.print(F("."));
+ Serial.print(status);
+ status = WiFi.status();
+ }
+
+ Serial.println(F(" Connected!"));
+#else
+ /* Newer Ethernet shields have a
+ * MAC address printed on a sticker on the shield */
+ byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
+ IPAddress ip(192, 168, 1, 42);
+ IPAddress myDns(192, 168, 1, 1);
+ Ethernet.init(10); /* Most Arduino shields */
+ /* Ethernet.init(5); * MKR ETH Shield */
+ /* Ethernet.init(0); * Teensy 2.0 */
+ /* Ethernet.init(20); * Teensy++ 2.0 */
+ /* Ethernet.init(15); * ESP8266 with Adafruit FeatherWing Ethernet */
+ /* Ethernet.init(33); * ESP32 with Adafruit FeatherWing Ethernet */
+ Serial.println(F("Initialize Ethernet with DHCP:"));
+ if (Ethernet.begin(mac) == 0) {
+ Serial.println(F("Failed to configure Ethernet using DHCP"));
+ /* Check for Ethernet hardware present */
+ if (Ethernet.hardwareStatus() == EthernetNoHardware) {
+ Serial.println(F("Ethernet shield was not found."));
+ while (true) {
+ delay(1); /* do nothing */
+ }
+ }
+ if (Ethernet.linkStatus() == LinkOFF) {
+ Serial.println(F("Ethernet cable is not connected."));
+ }
+ /* try to configure using IP address instead of DHCP : */
+ Ethernet.begin(mac, ip, myDns);
+ }
+ else {
+ Serial.print(F(" DHCP assigned IP "));
+ Serial.println(Ethernet.localIP());
+ }
+ /* We'll assume the Ethernet connection is ready to go. */
+#endif
+
+ Serial.println(F("********************************************************"));
+ Serial.print(F(" wolfSSL Example Server IP = "));
+#if defined(USING_WIFI)
+ Serial.println(WiFi.localIP());
+#else
+ Serial.println(Ethernet.localIP());
+#endif
+ /* In server mode, there's no host definition. */
+ /* See companion example: wolfssl_client.ino */
+ Serial.println(F("********************************************************"));
+ Serial.println(F("Setup network complete."));
+
+ return ret;
+}
+
+/*****************************************************************************/
+/* Arduino setup_wolfssl() */
+/*****************************************************************************/
+int setup_wolfssl(void)
+{
+ int ret = 0;
+ WOLFSSL_METHOD* method;
+
+ /* Show a revision of wolfssl user_settings.h file in use when available: */
+#if defined(WOLFSSL_USER_SETTINGS_ID)
+ Serial.print(F("WOLFSSL_USER_SETTINGS_ID: "));
+ Serial.println(F(WOLFSSL_USER_SETTINGS_ID));
+#else
+ Serial.println(F("No WOLFSSL_USER_SETTINGS_ID found."));
+#endif
+
+#if defined(NO_WOLFSSL_SERVER)
+ Serial.println(F("wolfSSL server code disabled to save space."));
+#endif
+#if defined(NO_WOLFSSL_CLIENT)
+ Serial.println(F("wolfSSL client code disabled to save space."));
+#endif
+
+#if defined(DEBUG_WOLFSSL)
+ Serial.println(F("wolfSSL Debugging is available! (DEBUG_WOLFSSL)"));
+ #if defined(DEBUG_WOLFSSL_MESSAGES_ON)
+ Serial.println(F("Enabling verbose messages wolfSSL_Debugging_ON"));
+ wolfSSL_Debugging_ON();
+ #else
+ Serial.println(F("Enable verbose messages with wolfSSL_Debugging_ON"));
+ Serial.println(F("or define DEBUG_WOLFSSL_MESSAGES_ON"));
+ #endif
+#else
+ Serial.println(F("wolfSSL Debugging is Off! (enable with DEBUG_WOLFSSL)"));
+#endif
+
+ /* See ssl.c for TLS cache settings. Larger cache = use more RAM. */
+#if defined(NO_SESSION_CACHE)
+ Serial.println(F("wolfSSL TLS NO_SESSION_CACHE"));
+#elif defined(MICRO_SESSION_CACHEx)
+ Serial.println(F("wolfSSL TLS MICRO_SESSION_CACHE"));
+#elif defined(SMALL_SESSION_CACHE)
+ Serial.println(F("wolfSSL TLS SMALL_SESSION_CACHE"));
+#elif defined(MEDIUM_SESSION_CACHE)
+ Serial.println(F("wolfSSL TLS MEDIUM_SESSION_CACHE"));
+#elif defined(BIG_SESSION_CACHE)
+ Serial.println(F("wolfSSL TLS BIG_SESSION_CACHE"));
+#elif defined(HUGE_SESSION_CACHE)
+ Serial.println(F("wolfSSL TLS HUGE_SESSION_CACHE"));
+#elif defined(HUGE_SESSION_CACHE)
+ Serial.println(F("wolfSSL TLS HUGE_SESSION_CACHE"));
+#else
+ Serial.println(F("WARNING: Unknown or no TLS session cache setting."));
+ /* See wolfssl/src/ssl.c for amount of memory used.
+ * It is best on embedded devices to choose a TLS session cache size. */
+#endif
+
+ /* Initialize wolfSSL before assigning ctx */
+ ret = wolfSSL_Init();
+ if (ret == WOLFSSL_SUCCESS) {
+ Serial.println("Successfully called wolfSSL_Init");
+ }
+ else {
+ Serial.println("ERROR: wolfSSL_Init failed");
+ }
+
+ /* See companion server example with wolfSSLv23_server_method here.
+ * method = wolfSSLv23_client_method()); SSL 3.0 - TLS 1.3.
+ * method = wolfTLSv1_2_client_method(); only TLS 1.2
+ * method = wolfTLSv1_3_client_method(); only TLS 1.3
+ *
+ * see Arduino\libraries\wolfssl\src\user_settings.h */
+
+ Serial.println("Here we go!");
+
+#ifdef WOLFSSL_DTLS13
+ Serial.println(F("Setting wolfDTLSv1_3_client_method"));
+ method = wolfDTLSv1_3_server_method();
+#else
+ Serial.println(F("Setting wolfDTLSv1_2_client_method"));
+ method = wolfDTLSv1_2_servert_method();
+#endif
+ ctx = wolfSSL_CTX_new(method);
+ if (ctx == NULL) {
+ fail_wait();
+ }
+
+ if (method == NULL) {
+ Serial.println(F("Unable to get wolfssl client method"));
+ fail_wait();
+ }
+
+ ctx = wolfSSL_CTX_new(method);
+ if (ctx == NULL) {
+ Serial.println(F("unable to get ctx"));
+ fail_wait();
+ }
+
+ return ret;
+}
+
+/*****************************************************************************/
+/* Arduino setup_certificates() */
+/*****************************************************************************/
+int setup_certificates(void)
+{
+ int ret = 0;
+
+/* See user_settings.h that should have included wolfssl/certs_test.h */
+
+Serial.println(F("Initializing certificates..."));
+show_memory();
+
+ /* Load CA certificates */
+ if (ret == WOLFSSL_SUCCESS) {
+ /* caCertLoc[] = "../certs/ca-cert.pem"; */
+ ret = wolfSSL_CTX_load_verify_buffer(ctx,
+ CTX_CA_CERT,
+ CTX_CA_CERT_SIZE,
+ CTX_SERVER_CERT_TYPE);
+ }
+
+ /* If successful, Load server certificates */
+ Serial.println("Initializing certificates...");
+ ret = wolfSSL_CTX_use_certificate_buffer(ctx,
+ CTX_SERVER_CERT,
+ CTX_SERVER_CERT_SIZE,
+ CTX_CA_CERT_TYPE);
+
+ if (ret == WOLFSSL_SUCCESS) {
+ Serial.print("Success: use certificate: ");
+ Serial.println(xstr(CTX_SERVER_CERT));
+ }
+ else {
+ Serial.print("Error: wolfSSL_CTX_use_certificate_buffer failed: ");
+ wc_ErrorString(ret, wc_error_message);
+ Serial.println(wc_error_message);
+ fail_wait();
+ }
+
+ /* Setup private server key */
+ ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx,
+ CTX_SERVER_KEY,
+ CTX_SERVER_KEY_SIZE,
+ CTX_SERVER_KEY_TYPE);
+ if (ret == WOLFSSL_SUCCESS) {
+ Serial.print("Success: use private key buffer: ");
+ Serial.println(xstr(CTX_SERVER_KEY));
+ }
+ else {
+ Serial.print("Error: wolfSSL_CTX_use_PrivateKey_buffer failed: ");
+ wc_ErrorString(ret, wc_error_message);
+ Serial.println(wc_error_message);
+ fail_wait();
+ }
+
+ /* Setup private server key */
+ ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx,
+ CTX_SERVER_KEY,
+ CTX_SERVER_KEY_SIZE,
+ CTX_SERVER_KEY_TYPE);
+
+ if (ret == WOLFSSL_SUCCESS) {
+ Serial.print("Success: use private key buffer: ");
+ Serial.println(xstr(CTX_SERVER_KEY));
+ }
+ else {
+ Serial.print("Error: wolfSSL_CTX_use_PrivateKey_buffer failed: ");
+ wc_ErrorString(ret, wc_error_message);
+ Serial.println(wc_error_message);
+ fail_wait();
+ }
+
+ return ret;
+} /* Arduino setup */
+
+/*****************************************************************************/
+/*****************************************************************************/
+/* Arduino setup() */
+/*****************************************************************************/
+/*****************************************************************************/
+void setup(void)
+{
+ int i = 0;
+ Serial.begin(SERIAL_BAUD);
+ while (!Serial && (i < 10)) {
+ /* wait for serial port to connect. Needed for native USB port only */
+ delay(1000);
+ i++;
+ }
+
+ Serial.println(F(""));
+ Serial.println(F(""));
+ Serial.println(F("wolfSSL DTLS Server Example Startup."));
+
+ /* Optionally pre-allocate a large block of memory for testing */
+#if defined(MEMORY_STRESS_TEST)
+ Serial.println(F("WARNING: Memory Stress Test Active!"));
+ Serial.print(F("Allocating extra memory: "));
+ Serial.print(MEMORY_STRESS_INITIAL);
+ Serial.println(F(" bytes..."));
+ memory_stress[mem_ctr] = (char*)malloc(MEMORY_STRESS_INITIAL);
+ show_memory();
+#endif
+
+ setup_hardware();
+
+ setup_network();
+
+ setup_datetime();
+
+ setup_wolfssl();
+
+ setup_certificates();
+
+#if defined THIS_USER_SETTINGS_VERSION
+ Serial.print(F("This user_settings.h version:"))
+ Serial.println(THIS_USER_SETTINGS_VERSION)
+#endif
+
+ /* Start the server
+ * See https://www.arduino.cc/reference/en/libraries/ethernet/server.begin/
+ */
+
+ Serial.println(F("Completed Arduino setup()"));
+
+ server.begin();
+ Serial.println("Begin Server... (waiting for remote client to connect)");
+
+ /* See companion wolfssl_client.ino code */
+ return;
+} /* Arduino setup */
+
+/*****************************************************************************/
+/* wolfSSL error_check() */
+/*****************************************************************************/
+int error_check(int this_ret, bool halt_on_error,
+ const __FlashStringHelper* message) {
+ int ret = 0;
+ if (this_ret == WOLFSSL_SUCCESS) {
+ Serial.print(F("Success: "));
+ Serial.println(message);
+ }
+ else {
+ Serial.print(F("ERROR: return = "));
+ Serial.print(this_ret);
+ Serial.print(F(": "));
+ Serial.println(message);
+ Serial.println(wc_GetErrorString(this_ret));
+ if (halt_on_error) {
+ fail_wait();
+ }
+ }
+ show_memory();
+
+ return ret;
+} /* error_check */
+
+/*****************************************************************************/
+/* wolfSSL error_check_ssl */
+/* Parameters: */
+/* ssl is the current WOLFSSL object pointer */
+/* halt_on_error set to true to suspend operations for critical error */
+/* message is expected to be a memory-efficient F("") macro string */
+/*****************************************************************************/
+int error_check_ssl(WOLFSSL* ssl, int this_ret, bool halt_on_error,
+ const __FlashStringHelper* message) {
+ int err = 0;
+
+ if (ssl == NULL) {
+ Serial.println(F("ssl is Null; Unable to allocate SSL object?"));
+#ifndef DEBUG_WOLFSSL
+ Serial.println(F("Define DEBUG_WOLFSSL in user_settings.h for more."));
+#else
+ Serial.println(F("See wolfssl/wolfcrypt/error-crypt.h for codes."));
+#endif
+ Serial.print(F("ERROR: "));
+ Serial.println(message);
+ show_memory();
+ if (halt_on_error) {
+ fail_wait();
+ }
+ }
+ else {
+ err = wolfSSL_get_error(ssl, this_ret);
+ if (err == WOLFSSL_SUCCESS) {
+ Serial.print(F("Success m: "));
+ Serial.println(message);
+ }
+ else {
+ if (err < 0) {
+ wolfSSL_ERR_error_string(err, errBuf);
+ Serial.print(F("WOLFSSL Error: "));
+ Serial.print(err);
+ Serial.print(F("; "));
+ Serial.println(errBuf);
+ }
+ else {
+ Serial.println(F("Success: ssl object."));
+ }
+ }
+ }
+
+ return err;
+} /* error_check_ssl */
+
+static void sig_handler(const int sig);
+static void free_resources(void);
+
+/*****************************************************************************/
+/*****************************************************************************/
+/* Arduino loop() */
+/*****************************************************************************/
+/*****************************************************************************/
+void loop()
+{
+ int exitVal = 1;
+ struct sockaddr_in servAddr; /* our server's address */
+ struct sockaddr_in cliaddr; /* the client's address */
+ int ret;
+ int err;
+ int recvLen = 0; /* length of message */
+ socklen_t cliLen;
+ char buff[MAXLINE]; /* the incoming message */
+ char ack[] = "I hear you fashizzle!\n";
+
+ /* Initialize wolfSSL before assigning ctx */
+ if (wolfSSL_Init() != WOLFSSL_SUCCESS) {
+ fprintf(stderr, "wolfSSL_Init error.\n");
+ fail_wait();
+ }
+
+ /* No-op when debugging is not compiled in */
+ wolfSSL_Debugging_ON();
+
+
+ /* Create a UDP/IP socket */
+ if ((listenfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
+ perror("socket()");
+ goto cleanup;
+ }
+ printf("Socket allocated\n");
+ memset((char *)&servAddr, 0, sizeof(servAddr));
+ /* host-to-network-long conversion (htonl) */
+ /* host-to-network-short conversion (htons) */
+ servAddr.sin_family = AF_INET;
+ servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ servAddr.sin_port = htons(WOLFSSL_PORT);
+
+ /* Bind Socket */
+ if (bind(listenfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) < 0) {
+ perror("bind()");
+ goto cleanup;
+ }
+
+ // signal(SIGINT, sig_handler);
+
+ while (1) {
+ printf("Awaiting client connection on port %d\n", WOLFSSL_PORT);
+
+ cliLen = sizeof(cliaddr);
+ ret = (int)recvfrom(listenfd, (char *)&buff, sizeof(buff), MSG_PEEK,
+ (struct sockaddr*)&cliaddr, &cliLen);
+
+ if (ret < 0) {
+ perror("recvfrom()");
+ goto cleanup;
+ }
+ else if (ret == 0) {
+ fprintf(stderr, "recvfrom zero return\n");
+ goto cleanup;
+ }
+
+ /* Create the WOLFSSL Object */
+ if ((ssl = wolfSSL_new(ctx)) == NULL) {
+ fprintf(stderr, "wolfSSL_new error.\n");
+ goto cleanup;
+ }
+
+ if (wolfSSL_dtls_set_peer(ssl, &cliaddr, cliLen) != WOLFSSL_SUCCESS) {
+ fprintf(stderr, "wolfSSL_dtls_set_peer error.\n");
+ goto cleanup;
+ }
+
+ if (wolfSSL_set_fd(ssl, listenfd) != WOLFSSL_SUCCESS) {
+ fprintf(stderr, "wolfSSL_set_fd error.\n");
+ break;
+ }
+
+ if (wolfSSL_accept(ssl) != WOLFSSL_SUCCESS) {
+ err = wolfSSL_get_error(ssl, 0);
+ fprintf(stderr, "error = %d, %s\n", err,
+ wolfSSL_ERR_reason_error_string(err));
+ fprintf(stderr, "SSL_accept failed.\n");
+ goto cleanup;
+ }
+
+ while (1) {
+ if ((recvLen = wolfSSL_read(ssl, buff, sizeof(buff)-1)) > 0) {
+ printf("heard %d bytes\n", recvLen);
+
+ buff[recvLen] = '\0';
+ printf("I heard this: \"%s\"\n", buff);
+ }
+ else if (recvLen <= 0) {
+ err = wolfSSL_get_error(ssl, 0);
+ if (err == WOLFSSL_ERROR_ZERO_RETURN) /* Received shutdown */
+ break;
+ fprintf(stderr, "error = %d, %s\n", err,
+ wolfSSL_ERR_reason_error_string(err));
+ fprintf(stderr, "SSL_read failed.\n");
+ goto cleanup;
+ }
+ printf("Sending reply.\n");
+ if (wolfSSL_write(ssl, ack, sizeof(ack)) < 0) {
+ err = wolfSSL_get_error(ssl, 0);
+ fprintf(stderr, "error = %d, %s\n", err,
+ wolfSSL_ERR_reason_error_string(err));
+ fprintf(stderr, "wolfSSL_write failed.\n");
+ goto cleanup;
+ }
+ }
+
+ printf("reply sent \"%s\"\n", ack);
+
+ /* Attempt a full shutdown */
+ ret = wolfSSL_shutdown(ssl);
+ if (ret == WOLFSSL_SHUTDOWN_NOT_DONE)
+ ret = wolfSSL_shutdown(ssl);
+ if (ret != WOLFSSL_SUCCESS) {
+ err = wolfSSL_get_error(ssl, 0);
+ fprintf(stderr, "err = %d, %s\n", err,
+ wolfSSL_ERR_reason_error_string(err));
+ fprintf(stderr, "wolfSSL_shutdown failed\n");
+ }
+ wolfSSL_free(ssl);
+ ssl = NULL;
+
+ printf("Awaiting new connection\n");
+ }
+
+ exitVal = 0;
+cleanup:
+ free_resources();
+ wolfSSL_Cleanup();
+
+ Serial.println(F("Done!"));
+ while (1) {
+ delay(1000);
+ }
+}
+
+
+static void sig_handler(const int sig)
+{
+ (void)sig;
+ free_resources();
+ wolfSSL_Cleanup();
+}
+
+static void free_resources(void)
+{
+ if (ssl != NULL) {
+ wolfSSL_shutdown(ssl);
+ wolfSSL_free(ssl);
+ ssl = NULL;
+ }
+ if (ctx != NULL) {
+ wolfSSL_CTX_free(ctx);
+ ctx = NULL;
+ }
+ if (listenfd != INVALID_SOCKET) {
+ close(listenfd);
+ listenfd = INVALID_SOCKET;
+ }
+}
+
diff --git a/Arduino/sketches/wolfssl_version/wolfssl_version.ino b/Arduino/sketches/wolfssl_version/wolfssl_version.ino
index 12be948f..ac34124b 100644
--- a/Arduino/sketches/wolfssl_version/wolfssl_version.ino
+++ b/Arduino/sketches/wolfssl_version/wolfssl_version.ino
@@ -6,7 +6,7 @@
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
@@ -21,6 +21,13 @@
#include
+#if defined(ARDUINO_PORTENTA_X8)
+ /* The Portenta is a Linux device. See wolfSSL examples:
+ * https://github.com/wolfSSL/wolfssl/tree/master/examples
+ * By default Serial is disabled and mapped to ErrorSerial */
+ #include
+#endif
+
/* wolfSSL user_settings.h must be included from settings.h
* Make all configurations changes in user_settings.h
* Do not edit wolfSSL `settings.h` or `config.h` files.