├── .github └── workflows │ └── sync-labels.yml ├── .gitignore ├── .travis.yml ├── README.md ├── assets └── default.html ├── build.sh ├── firmwares ├── NINA │ ├── 1.0.0 │ │ └── NINA_W102.bin │ ├── 1.1.0 │ │ └── NINA_W102.bin │ ├── 1.2.1 │ │ ├── NINA_W102-Uno_WiFi_Rev2.bin │ │ └── NINA_W102.bin │ ├── 1.2.2 │ │ ├── NINA_W102-Uno_WiFi_Rev2.bin │ │ └── NINA_W102.bin │ ├── 1.2.3 │ │ ├── NINA_W102-Uno_WiFi_Rev2.bin │ │ └── NINA_W102.bin │ ├── 1.2.4 │ │ ├── NINA_W102-Uno_WiFi_Rev2.bin │ │ └── NINA_W102.bin │ ├── 1.3.0 │ │ ├── NINA_W102-Uno_WiFi_Rev2.bin │ │ └── NINA_W102.bin │ ├── 1.4.0 │ │ ├── NINA_W102-Uno_WiFi_Rev2.bin │ │ └── NINA_W102.bin │ ├── 1.4.1 │ │ ├── NINA_W102-Uno_WiFi_Rev2.bin │ │ └── NINA_W102.bin │ ├── 1.4.2 │ │ ├── NINA_W102-Uno_WiFi_Rev2.bin │ │ └── NINA_W102.bin │ ├── 1.4.3 │ │ ├── NINA_W102-Uno_WiFi_Rev2.bin │ │ └── NINA_W102.bin │ ├── 1.4.4 │ │ ├── NINA_W102-Uno_WiFi_Rev2.bin │ │ └── NINA_W102.bin │ ├── 1.4.5 │ │ ├── NINA_W102-Nano_RP2040_Connect.bin │ │ ├── NINA_W102-Uno_WiFi_Rev2.bin │ │ └── NINA_W102.bin │ ├── 1.4.6 │ │ ├── NINA_W102-Nano_RP2040_Connect.bin │ │ ├── NINA_W102-Uno_WiFi_Rev2.bin │ │ └── NINA_W102.bin │ ├── 1.4.7 │ │ ├── NINA_W102-Nano_RP2040_Connect.bin │ │ ├── NINA_W102-Uno_WiFi_Rev2.bin │ │ └── NINA_W102.bin │ └── 1.4.8 │ │ ├── NINA_W102-Nano_RP2040_Connect.bin │ │ ├── NINA_W102-Uno_WiFi_Rev2.bin │ │ └── NINA_W102.bin └── WINC1500 │ ├── 19.4.4 │ ├── m2m_aio_2b0.bin │ └── m2m_aio_3a0.bin │ ├── 19.5.2 │ └── m2m_aio_3a0.bin │ ├── 19.5.4 │ └── m2m_aio_3a0.bin │ └── 19.6.1 │ └── m2m_aio_3a0.bin ├── screenshot-0.png ├── screenshot-1.png ├── screenshot-2.png └── src └── cc └── arduino └── plugins └── wifi101 ├── CertificateListModel.java ├── SerialPortListModel.java ├── UpdaterImpl.java ├── UpdaterJFrame.java ├── WiFi101.java ├── certs ├── WiFi101Certificate.java └── WiFi101CertificateBundle.java └── flashers ├── Flasher.java └── java ├── FlasherSerialClient.java ├── NinaFlasher.java ├── SSLCertDownloader.java └── WINCFlasher.java /.github/workflows/sync-labels.yml: -------------------------------------------------------------------------------- 1 | # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/sync-labels.md 2 | name: Sync Labels 3 | 4 | # See: https://docs.github.com/en/actions/reference/events-that-trigger-workflows 5 | on: 6 | push: 7 | paths: 8 | - ".github/workflows/sync-labels.ya?ml" 9 | - ".github/label-configuration-files/*.ya?ml" 10 | pull_request: 11 | paths: 12 | - ".github/workflows/sync-labels.ya?ml" 13 | - ".github/label-configuration-files/*.ya?ml" 14 | schedule: 15 | # Run daily at 8 AM UTC to sync with changes to shared label configurations. 16 | - cron: "0 8 * * *" 17 | workflow_dispatch: 18 | repository_dispatch: 19 | 20 | env: 21 | CONFIGURATIONS_FOLDER: .github/label-configuration-files 22 | CONFIGURATIONS_ARTIFACT: label-configuration-files 23 | 24 | jobs: 25 | check: 26 | runs-on: ubuntu-latest 27 | 28 | steps: 29 | - name: Checkout repository 30 | uses: actions/checkout@v2 31 | 32 | - name: Download JSON schema for labels configuration file 33 | id: download-schema 34 | uses: carlosperate/download-file-action@v1 35 | with: 36 | file-url: https://raw.githubusercontent.com/arduino/tooling-project-assets/main/workflow-templates/assets/sync-labels/arduino-tooling-gh-label-configuration-schema.json 37 | location: ${{ runner.temp }}/label-configuration-schema 38 | 39 | - name: Install JSON schema validator 40 | run: | 41 | sudo npm install \ 42 | --global \ 43 | ajv-cli \ 44 | ajv-formats 45 | 46 | - name: Validate local labels configuration 47 | run: | 48 | # See: https://github.com/ajv-validator/ajv-cli#readme 49 | ajv validate \ 50 | --all-errors \ 51 | -c ajv-formats \ 52 | -s "${{ steps.download-schema.outputs.file-path }}" \ 53 | -d "${{ env.CONFIGURATIONS_FOLDER }}/*.{yml,yaml}" 54 | 55 | download: 56 | needs: check 57 | runs-on: ubuntu-latest 58 | 59 | strategy: 60 | matrix: 61 | filename: 62 | # Filenames of the shared configurations to apply to the repository in addition to the local configuration. 63 | # https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/sync-labels 64 | - universal.yml 65 | - tooling.yml 66 | 67 | steps: 68 | - name: Download 69 | uses: carlosperate/download-file-action@v1 70 | with: 71 | file-url: https://raw.githubusercontent.com/arduino/tooling-project-assets/main/workflow-templates/assets/sync-labels/${{ matrix.filename }} 72 | 73 | - name: Pass configuration files to next job via workflow artifact 74 | uses: actions/upload-artifact@v2 75 | with: 76 | path: | 77 | *.yaml 78 | *.yml 79 | if-no-files-found: error 80 | name: ${{ env.CONFIGURATIONS_ARTIFACT }} 81 | 82 | sync: 83 | needs: download 84 | runs-on: ubuntu-latest 85 | 86 | steps: 87 | - name: Set environment variables 88 | run: | 89 | # See: https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable 90 | echo "MERGED_CONFIGURATION_PATH=${{ runner.temp }}/labels.yml" >> "$GITHUB_ENV" 91 | 92 | - name: Determine whether to dry run 93 | id: dry-run 94 | if: > 95 | github.event_name == 'pull_request' || 96 | ( 97 | ( 98 | github.event_name == 'push' || 99 | github.event_name == 'workflow_dispatch' 100 | ) && 101 | github.ref != format('refs/heads/{0}', github.event.repository.default_branch) 102 | ) 103 | run: | 104 | # Use of this flag in the github-label-sync command will cause it to only check the validity of the 105 | # configuration. 106 | echo "::set-output name=flag::--dry-run" 107 | 108 | - name: Checkout repository 109 | uses: actions/checkout@v2 110 | 111 | - name: Download configuration files artifact 112 | uses: actions/download-artifact@v2 113 | with: 114 | name: ${{ env.CONFIGURATIONS_ARTIFACT }} 115 | path: ${{ env.CONFIGURATIONS_FOLDER }} 116 | 117 | - name: Remove unneeded artifact 118 | uses: geekyeggo/delete-artifact@v1 119 | with: 120 | name: ${{ env.CONFIGURATIONS_ARTIFACT }} 121 | 122 | - name: Merge label configuration files 123 | run: | 124 | # Merge all configuration files 125 | shopt -s extglob 126 | cat "${{ env.CONFIGURATIONS_FOLDER }}"/*.@(yml|yaml) > "${{ env.MERGED_CONFIGURATION_PATH }}" 127 | 128 | - name: Install github-label-sync 129 | run: sudo npm install --global github-label-sync 130 | 131 | - name: Sync labels 132 | env: 133 | GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} 134 | run: | 135 | # See: https://github.com/Financial-Times/github-label-sync 136 | github-label-sync \ 137 | --labels "${{ env.MERGED_CONFIGURATION_PATH }}" \ 138 | ${{ steps.dry-run.outputs.flag }} \ 139 | ${{ github.repository }} 140 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | dist 3 | .classpath 4 | .project 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | 3 | language: java 4 | 5 | os: 6 | - linux 7 | 8 | addons: 9 | apt: 10 | packages: 11 | - ant 12 | 13 | jdk: 14 | - openjdk8 15 | 16 | script: 17 | - export SRC=$PWD 18 | - export TAG=1.8.13 19 | - wget https://github.com/arduino/Arduino/archive/$TAG.zip 20 | - unzip $TAG.zip 21 | - pushd Arduino-$TAG/build 22 | - echo "" | ant build 23 | - popd 24 | - export IDE_FOLDER=Arduino-$TAG/build/linux/work 25 | - ./build.sh 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WiFi101 Firmware Updater Tool for Arduino IDE [![Build Status](https://travis-ci.org/arduino-libraries/WiFi101-FirmwareUpdater-Plugin.svg?branch=master)](https://travis-ci.org/arduino-libraries/WiFi101-FirmwareUpdater-Plugin) 2 | 3 | This plugin is a GUI to update Firmware or SSL Certificates on shield or boards based 4 | on the Atmel WINC1500 WiFi chipset (for example the Arduino WiFi 101 Shield or the 5 | Arduino/Genuino MKR1000 board). This plugin is bundled with the IDE starting from v.1.6.10 6 | 7 | ## Installation 8 | 9 | - Download the tool [from this page](https://github.com/arduino-libraries/WiFi101-FirmwareUpdater-Plugin/releases/latest). 10 | - Create a `tools` folder in your sketchbook, if it doesn't exist yet. 11 | - Unpack the zip archive into `tools` folder (it will look like `.../Arduino/tools/WiFi101/tool/WiFi101.jar`) 12 | - Restart the Arduino IDE. 13 | 14 | ## Usage 15 | 16 | - Follow instructions [on this page](https://www.arduino.cc/en/Tutorial/FirmwareUpdater). 17 | 18 | ## Screenshots 19 | 20 | ![Screenshot](screenshot-0.png) 21 | 22 | ![Screenshot](screenshot-1.png) 23 | 24 | ![Screenshot](screenshot-2.png) 25 | 26 | ## Issues and suggestions 27 | 28 | Please open an issue [on github](https://github.com/arduino-libraries/WiFi101-FirmwareUpdater-Plugin/issues/new). 29 | 30 | ### Security 31 | 32 | If you think you found a vulnerability or other security-related bug in this project, please read our 33 | [security policy](https://github.com/arduino/WiFi101-FirmwareUpdater-Plugin/security/policy) and report the bug to our 34 | Security Team 🛡️ 35 | Thank you! 36 | 37 | e-mail contact: security@arduino.cc 38 | 39 | ## Credits and license 40 | 41 | ``` 42 | Copyright 2016 Arduino LLC (http://www.arduino.cc/) 43 | 44 | Arduino is free software; you can redistribute it and/or modify 45 | it under the terms of the GNU General Public License as published by 46 | the Free Software Foundation; either version 2 of the License, or 47 | (at your option) any later version. 48 | 49 | This program is distributed in the hope that it will be useful, 50 | but WITHOUT ANY WARRANTY; without even the implied warranty of 51 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 52 | GNU General Public License for more details. 53 | 54 | You should have received a copy of the GNU General Public License 55 | along with this program; if not, write to the Free Software 56 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 57 | 58 | As a special exception, you may use this file as part of a free software 59 | library without restriction. Specifically, if other files instantiate 60 | templates or use macros or inline functions from this file, or you compile 61 | this file and link it with other files to produce an executable, this 62 | file does not by itself cause the resulting executable to be covered by 63 | the GNU General Public License. This exception does not however 64 | invalidate any other reasons why the executable file might be covered by 65 | the GNU General Public License. 66 | ``` 67 | 68 | -------------------------------------------------------------------------------- /assets/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Log In 6 | 67 | 91 | 92 | 93 | 136 |
137 |
138 |
139 | SSID:
140 |
141 | PASSWORD:
142 |
143 | 144 | 145 |
146 |
147 |

Please enter your WiFi network credentials. 148 |
Then the board will attempt to connect to your WiFi network.
149 |

150 |
151 |
152 |
153 | 154 | 155 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This file is part of WiFi101 Updater Arduino-IDE Plugin. 4 | # Copyright 2016 Arduino LLC (http://www.arduino.cc/) 5 | # 6 | # Arduino is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program; if not, write to the Free Software 18 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | # 20 | # As a special exception, you may use this file as part of a free software 21 | # library without restriction. Specifically, if other files instantiate 22 | # templates or use macros or inline functions from this file, or you compile 23 | # this file and link it with other files to produce an executable, this 24 | # file does not by itself cause the resulting executable to be covered by 25 | # the GNU General Public License. This exception does not however 26 | # invalidate any other reasons why the executable file might be covered by 27 | # the GNU General Public License. 28 | 29 | REV=0.12.0 30 | ZIP_FILENAME=WiFi101-Updater-ArduinoIDE-Plugin-$REV 31 | REQUIRED_JARS="pde.jar arduino-core.jar jssc-2.8.0-arduino4.jar bcpg-jdk15on-152.jar bcprov-jdk15on-152.jar commons-lang3-3.8.1.jar commons-codec-1.7.jar" 32 | 33 | # Check existence of the IDE folder 34 | if [ -z "$IDE_FOLDER" ]; then 35 | echo "" 36 | echo "Please set variable IDE_FOLDER to the path of the installed Arduino IDE" 37 | echo "For example:" 38 | echo "" 39 | echo "IDE_FOLDER=/home/user/ArduinoIDE/ ./build.sh" 40 | echo "" 41 | exit 1 42 | fi 43 | 44 | # Check needed libraries 45 | CLASSPATH="src" 46 | for JAR in $REQUIRED_JARS; do 47 | case "$OSTYPE" in 48 | darwin*) JARFILE="$IDE_FOLDER/Java/$JAR" ;; 49 | *) JARFILE="$IDE_FOLDER/lib/$JAR" ;; 50 | esac 51 | if [ -z "$JARFILE" ]; then 52 | echo "Could not find $JARFILE library in you IDE folder." 53 | exit 1 54 | fi 55 | CLASSPATH="$CLASSPATH:$JARFILE" 56 | echo $JAR 57 | done 58 | 59 | # Create staging folder 60 | OUTPUT_FOLDER=`pwd`/WiFi101/tool 61 | mkdir -p $OUTPUT_FOLDER 62 | 63 | # Build java plugin 64 | mkdir -p build 65 | javac -target 1.8 -cp "$CLASSPATH" -d build src/cc/arduino/plugins/wifi101/WiFi101.java 66 | cd build 67 | zip -r $OUTPUT_FOLDER/WiFi101.jar * 68 | cd .. 69 | rm -r build 70 | 71 | # Copy resources 72 | cp -rv firmwares $OUTPUT_FOLDER 73 | 74 | # Create distribution .zip 75 | mkdir -p dist 76 | zip -r dist/$ZIP_FILENAME.zip WiFi101/ 77 | 78 | # Cleanup 79 | rm -r WiFi101 80 | 81 | # Install in current IDE 82 | case "$OSTYPE" in 83 | darwin*) unzip -o dist/$ZIP_FILENAME.zip -d $IDE_FOLDER/Java/tools ;; 84 | *) unzip -o dist/$ZIP_FILENAME.zip -d $IDE_FOLDER/tools ;; 85 | esac 86 | -------------------------------------------------------------------------------- /firmwares/NINA/1.0.0/NINA_W102.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.0.0/NINA_W102.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.1.0/NINA_W102.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.1.0/NINA_W102.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.2.1/NINA_W102-Uno_WiFi_Rev2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.2.1/NINA_W102-Uno_WiFi_Rev2.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.2.1/NINA_W102.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.2.1/NINA_W102.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.2.2/NINA_W102-Uno_WiFi_Rev2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.2.2/NINA_W102-Uno_WiFi_Rev2.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.2.2/NINA_W102.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.2.2/NINA_W102.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.2.3/NINA_W102-Uno_WiFi_Rev2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.2.3/NINA_W102-Uno_WiFi_Rev2.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.2.3/NINA_W102.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.2.3/NINA_W102.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.2.4/NINA_W102-Uno_WiFi_Rev2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.2.4/NINA_W102-Uno_WiFi_Rev2.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.2.4/NINA_W102.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.2.4/NINA_W102.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.3.0/NINA_W102-Uno_WiFi_Rev2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.3.0/NINA_W102-Uno_WiFi_Rev2.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.3.0/NINA_W102.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.3.0/NINA_W102.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.4.0/NINA_W102-Uno_WiFi_Rev2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.4.0/NINA_W102-Uno_WiFi_Rev2.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.4.0/NINA_W102.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.4.0/NINA_W102.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.4.1/NINA_W102-Uno_WiFi_Rev2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.4.1/NINA_W102-Uno_WiFi_Rev2.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.4.1/NINA_W102.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.4.1/NINA_W102.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.4.2/NINA_W102-Uno_WiFi_Rev2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.4.2/NINA_W102-Uno_WiFi_Rev2.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.4.2/NINA_W102.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.4.2/NINA_W102.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.4.3/NINA_W102-Uno_WiFi_Rev2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.4.3/NINA_W102-Uno_WiFi_Rev2.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.4.3/NINA_W102.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.4.3/NINA_W102.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.4.4/NINA_W102-Uno_WiFi_Rev2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.4.4/NINA_W102-Uno_WiFi_Rev2.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.4.4/NINA_W102.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.4.4/NINA_W102.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.4.5/NINA_W102-Nano_RP2040_Connect.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.4.5/NINA_W102-Nano_RP2040_Connect.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.4.5/NINA_W102-Uno_WiFi_Rev2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.4.5/NINA_W102-Uno_WiFi_Rev2.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.4.5/NINA_W102.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.4.5/NINA_W102.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.4.6/NINA_W102-Nano_RP2040_Connect.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.4.6/NINA_W102-Nano_RP2040_Connect.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.4.6/NINA_W102-Uno_WiFi_Rev2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.4.6/NINA_W102-Uno_WiFi_Rev2.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.4.6/NINA_W102.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.4.6/NINA_W102.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.4.7/NINA_W102-Nano_RP2040_Connect.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.4.7/NINA_W102-Nano_RP2040_Connect.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.4.7/NINA_W102-Uno_WiFi_Rev2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.4.7/NINA_W102-Uno_WiFi_Rev2.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.4.7/NINA_W102.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.4.7/NINA_W102.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.4.8/NINA_W102-Nano_RP2040_Connect.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.4.8/NINA_W102-Nano_RP2040_Connect.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.4.8/NINA_W102-Uno_WiFi_Rev2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.4.8/NINA_W102-Uno_WiFi_Rev2.bin -------------------------------------------------------------------------------- /firmwares/NINA/1.4.8/NINA_W102.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/NINA/1.4.8/NINA_W102.bin -------------------------------------------------------------------------------- /firmwares/WINC1500/19.4.4/m2m_aio_2b0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/WINC1500/19.4.4/m2m_aio_2b0.bin -------------------------------------------------------------------------------- /firmwares/WINC1500/19.4.4/m2m_aio_3a0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/WINC1500/19.4.4/m2m_aio_3a0.bin -------------------------------------------------------------------------------- /firmwares/WINC1500/19.5.2/m2m_aio_3a0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/WINC1500/19.5.2/m2m_aio_3a0.bin -------------------------------------------------------------------------------- /firmwares/WINC1500/19.5.4/m2m_aio_3a0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/WINC1500/19.5.4/m2m_aio_3a0.bin -------------------------------------------------------------------------------- /firmwares/WINC1500/19.6.1/m2m_aio_3a0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/firmwares/WINC1500/19.6.1/m2m_aio_3a0.bin -------------------------------------------------------------------------------- /screenshot-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/screenshot-0.png -------------------------------------------------------------------------------- /screenshot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/screenshot-1.png -------------------------------------------------------------------------------- /screenshot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/WiFi101-FirmwareUpdater-Plugin/5886533edec709305f2ad9681bcf0312cf516e53/screenshot-2.png -------------------------------------------------------------------------------- /src/cc/arduino/plugins/wifi101/CertificateListModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WiFi101 Updater Arduino-IDE Plugin. 3 | * Copyright 2016 Arduino LLC (http://www.arduino.cc/) 4 | * 5 | * Arduino is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | * 19 | * As a special exception, you may use this file as part of a free software 20 | * library without restriction. Specifically, if other files instantiate 21 | * templates or use macros or inline functions from this file, or you compile 22 | * this file and link it with other files to produce an executable, this 23 | * file does not by itself cause the resulting executable to be covered by 24 | * the GNU General Public License. This exception does not however 25 | * invalidate any other reasons why the executable file might be covered by 26 | * the GNU General Public License. 27 | */ 28 | package cc.arduino.plugins.wifi101; 29 | 30 | import java.util.List; 31 | 32 | import javax.swing.ListModel; 33 | import javax.swing.event.ListDataListener; 34 | 35 | public class CertificateListModel implements ListModel { 36 | 37 | private List list; 38 | 39 | public CertificateListModel(List _list) { 40 | list = _list; 41 | } 42 | 43 | @Override 44 | public int getSize() { 45 | return list.size(); 46 | } 47 | 48 | @Override 49 | public String getElementAt(int index) { 50 | return list.get(index); 51 | } 52 | 53 | @Override 54 | public void addListDataListener(ListDataListener l) { 55 | } 56 | 57 | @Override 58 | public void removeListDataListener(ListDataListener l) { 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/cc/arduino/plugins/wifi101/SerialPortListModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WiFi101 Updater Arduino-IDE Plugin. 3 | * Copyright 2016 Arduino LLC (http://www.arduino.cc/) 4 | * 5 | * Arduino is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | * 19 | * As a special exception, you may use this file as part of a free software 20 | * library without restriction. Specifically, if other files instantiate 21 | * templates or use macros or inline functions from this file, or you compile 22 | * this file and link it with other files to produce an executable, this 23 | * file does not by itself cause the resulting executable to be covered by 24 | * the GNU General Public License. This exception does not however 25 | * invalidate any other reasons why the executable file might be covered by 26 | * the GNU General Public License. 27 | */ 28 | package cc.arduino.plugins.wifi101; 29 | 30 | import java.util.List; 31 | 32 | import javax.swing.ListModel; 33 | import javax.swing.event.ListDataListener; 34 | 35 | import cc.arduino.packages.BoardPort; 36 | import processing.app.Base; 37 | 38 | class SerialPortListModel implements ListModel { 39 | 40 | private List ports; 41 | 42 | public SerialPortListModel() { 43 | ports = Base.getDiscoveryManager().discovery(); 44 | ports.removeIf(port -> !port.getProtocol().equals("serial")); 45 | } 46 | 47 | @Override 48 | public int getSize() { 49 | return ports.size(); 50 | } 51 | 52 | @Override 53 | public String getElementAt(int index) { 54 | return ports.get(index).getAddress(); 55 | } 56 | 57 | @Override 58 | public void addListDataListener(ListDataListener l) { 59 | } 60 | 61 | @Override 62 | public void removeListDataListener(ListDataListener l) { 63 | } 64 | 65 | public BoardPort getPort(int index) { 66 | return ports.get(index); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/cc/arduino/plugins/wifi101/UpdaterImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WiFi101 Updater Arduino-IDE Plugin. 3 | * Copyright 2016 Arduino LLC (http://www.arduino.cc/) 4 | * 5 | * Arduino is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | * 19 | * As a special exception, you may use this file as part of a free software 20 | * library without restriction. Specifically, if other files instantiate 21 | * templates or use macros or inline functions from this file, or you compile 22 | * this file and link it with other files to produce an executable, this 23 | * file does not by itself cause the resulting executable to be covered by 24 | * the GNU General Public License. This exception does not however 25 | * invalidate any other reasons why the executable file might be covered by 26 | * the GNU General Public License. 27 | */ 28 | package cc.arduino.plugins.wifi101; 29 | 30 | import static java.util.Arrays.asList; 31 | 32 | import java.util.ArrayList; 33 | import java.util.List; 34 | 35 | import javax.swing.DefaultListModel; 36 | import javax.swing.JOptionPane; 37 | 38 | import cc.arduino.packages.BoardPort; 39 | import cc.arduino.plugins.wifi101.flashers.Flasher; 40 | import cc.arduino.plugins.wifi101.flashers.java.NinaFlasher; 41 | import cc.arduino.plugins.wifi101.flashers.java.WINCFlasher; 42 | import processing.app.Base; 43 | 44 | @SuppressWarnings("serial") 45 | public class UpdaterImpl extends UpdaterJFrame { 46 | private SerialPortListModel listModel; 47 | private List websites = new ArrayList<>(); 48 | 49 | public ArrayList compatibleBoard; 50 | 51 | public static ArrayList fwAvailable = new ArrayList<>(); 52 | 53 | public UpdaterImpl() throws Exception { 54 | super(); 55 | Base.registerWindowCloseKeys(getRootPane(), e -> { 56 | setVisible(false); 57 | }); 58 | Base.setIcon(this); 59 | 60 | fwAvailable.add(new WINCFlasher("WINC1501 Model B", "19.6.1", "firmwares/WINC1500/19.6.1/m2m_aio_3a0.bin", true, 1000000, asList("Arduino/Genuino MKR1000"))); 61 | fwAvailable.add(new WINCFlasher("WINC1501 Model B", "19.5.4", "firmwares/WINC1500/19.5.4/m2m_aio_3a0.bin", true, 1000000, asList("Arduino/Genuino MKR1000"))); 62 | fwAvailable.add(new WINCFlasher("WINC1501 Model B", "19.5.2", "firmwares/WINC1500/19.5.2/m2m_aio_3a0.bin", true, 1000000, asList("Arduino/Genuino MKR1000"))); 63 | fwAvailable.add(new WINCFlasher("WINC1501 Model B", "19.4.4", "firmwares/WINC1500/19.4.4/m2m_aio_3a0.bin", true, 1000000, asList("Arduino/Genuino MKR1000"))); 64 | fwAvailable.add(new WINCFlasher("WINC1501 Model A", "19.4.4", "firmwares/WINC1500/19.4.4/m2m_aio_2b0.bin", true, 115200, asList("Arduino WiFi 101 Shield"))); 65 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.4.8", "firmwares/NINA/1.4.8/NINA_W102.bin", true, 1000000, asList("Arduino MKR WiFi 1010", "Arduino NANO 33 IoT"))); 66 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.4.8", "firmwares/NINA/1.4.8/NINA_W102-Uno_WiFi_Rev2.bin", true, 1000000, asList("Arduino Uno WiFi Rev2"))); 67 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.4.8", "firmwares/NINA/1.4.8/NINA_W102-Nano_RP2040_Connect.bin", true, 1000000, asList("Arduino Nano RP2040 Connect"))); 68 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.4.7", "firmwares/NINA/1.4.7/NINA_W102.bin", true, 1000000, asList("Arduino MKR WiFi 1010", "Arduino NANO 33 IoT"))); 69 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.4.7", "firmwares/NINA/1.4.7/NINA_W102-Uno_WiFi_Rev2.bin", true, 1000000, asList("Arduino Uno WiFi Rev2"))); 70 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.4.7", "firmwares/NINA/1.4.7/NINA_W102-Nano_RP2040_Connect.bin", true, 1000000, asList("Arduino Nano RP2040 Connect"))); 71 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.4.6", "firmwares/NINA/1.4.6/NINA_W102.bin", true, 1000000, asList("Arduino MKR WiFi 1010", "Arduino NANO 33 IoT"))); 72 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.4.6", "firmwares/NINA/1.4.6/NINA_W102-Uno_WiFi_Rev2.bin", true, 1000000, asList("Arduino Uno WiFi Rev2"))); 73 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.4.6", "firmwares/NINA/1.4.6/NINA_W102-Nano_RP2040_Connect.bin", true, 1000000, asList("Arduino Nano RP2040 Connect"))); 74 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.4.5", "firmwares/NINA/1.4.5/NINA_W102.bin", true, 1000000, asList("Arduino MKR WiFi 1010", "Arduino NANO 33 IoT"))); 75 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.4.5", "firmwares/NINA/1.4.5/NINA_W102-Uno_WiFi_Rev2.bin", true, 1000000, asList("Arduino Uno WiFi Rev2"))); 76 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.4.5", "firmwares/NINA/1.4.5/NINA_W102-Nano_RP2040_Connect.bin", true, 1000000, asList("Arduino Nano RP2040 Connect"))); 77 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.4.4", "firmwares/NINA/1.4.4/NINA_W102.bin", true, 1000000, asList("Arduino MKR WiFi 1010", "Arduino NANO 33 IoT"))); 78 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.4.4", "firmwares/NINA/1.4.4/NINA_W102-Uno_WiFi_Rev2.bin", true, 1000000, asList("Arduino Uno WiFi Rev2"))); 79 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.4.3", "firmwares/NINA/1.4.3/NINA_W102.bin", true, 1000000, asList("Arduino MKR WiFi 1010", "Arduino NANO 33 IoT"))); 80 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.4.3", "firmwares/NINA/1.4.3/NINA_W102-Uno_WiFi_Rev2.bin", true, 1000000, asList("Arduino Uno WiFi Rev2"))); 81 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.4.2", "firmwares/NINA/1.4.2/NINA_W102.bin", true, 1000000, asList("Arduino MKR WiFi 1010", "Arduino NANO 33 IoT"))); 82 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.4.2", "firmwares/NINA/1.4.2/NINA_W102-Uno_WiFi_Rev2.bin", true, 1000000, asList("Arduino Uno WiFi Rev2"))); 83 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.4.1", "firmwares/NINA/1.4.1/NINA_W102.bin", true, 1000000, asList("Arduino MKR WiFi 1010", "Arduino NANO 33 IoT"))); 84 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.4.1", "firmwares/NINA/1.4.1/NINA_W102-Uno_WiFi_Rev2.bin", true, 1000000, asList("Arduino Uno WiFi Rev2"))); 85 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.4.0", "firmwares/NINA/1.4.0/NINA_W102.bin", true, 1000000, asList("Arduino MKR WiFi 1010", "Arduino NANO 33 IoT"))); 86 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.4.0", "firmwares/NINA/1.4.0/NINA_W102-Uno_WiFi_Rev2.bin", true, 1000000, asList("Arduino Uno WiFi Rev2"))); 87 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.3.0", "firmwares/NINA/1.3.0/NINA_W102.bin", true, 1000000, asList("Arduino MKR WiFi 1010", "Arduino NANO 33 IoT"))); 88 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.3.0", "firmwares/NINA/1.3.0/NINA_W102-Uno_WiFi_Rev2.bin", true, 1000000, asList("Arduino Uno WiFi Rev2"))); 89 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.2.4", "firmwares/NINA/1.2.4/NINA_W102.bin", true, 1000000, asList("Arduino MKR WiFi 1010", "Arduino NANO 33 IoT"))); 90 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.2.4", "firmwares/NINA/1.2.4/NINA_W102-Uno_WiFi_Rev2.bin", true, 1000000, asList("Arduino Uno WiFi Rev2"))); 91 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.2.3", "firmwares/NINA/1.2.3/NINA_W102.bin", true, 1000000, asList("Arduino MKR WiFi 1010"))); 92 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.2.3", "firmwares/NINA/1.2.3/NINA_W102-Uno_WiFi_Rev2.bin", true, 1000000, asList("Arduino Uno WiFi Rev2"))); 93 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.2.2", "firmwares/NINA/1.2.2/NINA_W102.bin", true, 1000000, asList("Arduino MKR WiFi 1010"))); 94 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.2.2", "firmwares/NINA/1.2.2/NINA_W102-Uno_WiFi_Rev2.bin", true, 1000000, asList("Arduino Uno WiFi Rev2"))); 95 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.2.1", "firmwares/NINA/1.2.1/NINA_W102.bin", true, 1000000, asList("Arduino MKR WiFi 1010"))); 96 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.2.1", "firmwares/NINA/1.2.1/NINA_W102-Uno_WiFi_Rev2.bin", true, 1000000, asList("Arduino Uno WiFi Rev2"))); 97 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.1.0", "firmwares/NINA/1.1.0/NINA_W102.bin", true, 1000000, asList("Arduino MKR WiFi 1010", "Arduino MKR Vidor 4000", "Arduino Uno WiFi Rev2"))); 98 | fwAvailable.add(new NinaFlasher("NINA firmware", "1.0.0", "firmwares/NINA/1.0.0/NINA_W102.bin", false, 1000000, asList("Arduino MKR WiFi 1010", "Arduino MKR Vidor 4000", "Arduino Uno WiFi Rev2"))); 99 | 100 | for (Flasher firmware : fwAvailable) { 101 | getFirmwareSelector().addItem(firmware); 102 | } 103 | if (getSerialPortList().getModel().getSize() == 0) { 104 | setEnabledCommand(false); 105 | } 106 | refreshSerialPortList(); 107 | websites.add("arduino.cc:443"); 108 | refreshCertList(); 109 | } 110 | 111 | private void refreshCertList() { 112 | CertificateListModel model = new CertificateListModel(websites); 113 | getCertSelector().setModel(model); 114 | } 115 | 116 | @Override 117 | protected void refreshSerialPortList() { 118 | DefaultListModel model = new DefaultListModel<>(); 119 | BoardPort board; 120 | listModel = new SerialPortListModel(); 121 | for (int i = 0; i < listModel.getSize(); i++) { 122 | board = listModel.getPort(i); 123 | if (board.getBoardName() != null) { 124 | model.addElement(board.getBoardName().concat(" (").concat(board.getAddress()).concat(")")); 125 | } else { 126 | model.addElement(board.getAddress()); 127 | } 128 | } 129 | getSerialPortList().removeAll(); 130 | getSerialPortList().setModel(model); 131 | } 132 | 133 | @Override 134 | protected void updateCertSection() { 135 | Flasher fw = (Flasher) getFirmwareSelector().getSelectedItem(); 136 | if (fw != null) { 137 | hideCertificatePanel(fw.certificatesAvailable()); 138 | } 139 | } 140 | 141 | @Override 142 | protected void SelectBoardModule() { 143 | int added = 0; 144 | setEnabledCommand(true); 145 | hideCertificatePanel(true); 146 | getFirmwareSelector().removeAllItems(); 147 | if (getSelectedPort() != null) { 148 | for (Flasher firmware : fwAvailable) { 149 | if (firmware.isCompatible(getSelectedPort().getBoardName())) { 150 | getFirmwareSelector().addItem(firmware); 151 | added++; 152 | } 153 | } 154 | if (added == 0) { 155 | // Board not automatically recognized, give the chance to flash any firmware 156 | for (Flasher firmware : fwAvailable) { 157 | getFirmwareSelector().addItem(firmware); 158 | } 159 | } 160 | Flasher fw = (Flasher) getFirmwareSelector().getSelectedItem(); 161 | hideCertificatePanel(fw.certificatesAvailable()); 162 | } else { 163 | setEnabledCommand(false); 164 | hideCertificatePanel(false); 165 | } 166 | } 167 | 168 | private BoardPort getSelectedPort() { 169 | int i = getSerialPortList().getSelectedIndex(); 170 | if (i == -1) 171 | return null; 172 | return listModel.getPort(i); 173 | } 174 | 175 | @Override 176 | protected void testConnection() { 177 | Flasher fw = (Flasher) getFirmwareSelector().getSelectedItem(); 178 | fw.setProgressBar(getUpdateProgressBar()); 179 | BoardPort port = getSelectedPort(); 180 | if (port == null) { 181 | JOptionPane.showMessageDialog(UpdaterImpl.this, "Please select a port to run the test!"); 182 | return; 183 | } 184 | 185 | setEnabled(false); 186 | new Thread() { 187 | @Override 188 | public void run() { 189 | try { 190 | fw.testConnection(port.getAddress(), fw.getBaudrate()); 191 | JOptionPane.showMessageDialog(UpdaterImpl.this, "The programmer is working!", "Test successful", 192 | JOptionPane.INFORMATION_MESSAGE); 193 | } catch (Exception e) { 194 | e.printStackTrace(); 195 | JOptionPane.showMessageDialog(UpdaterImpl.this, e.getMessage(), "Connection error.", 196 | JOptionPane.ERROR_MESSAGE); 197 | } 198 | setEnabled(true); 199 | resetProgress(); 200 | } 201 | }.start(); 202 | } 203 | 204 | @Override 205 | protected void openFirmwareUpdaterSketch() { 206 | Flasher fw = (Flasher) getFirmwareSelector().getSelectedItem(); 207 | try { 208 | fw.openFirmwareUpdaterSketch(getSelectedPort()); 209 | } catch (NullPointerException e) { 210 | JOptionPane.showMessageDialog(UpdaterImpl.this, "Please select a board from the connected ones.", "No board selected", 211 | JOptionPane.INFORMATION_MESSAGE); 212 | 213 | } catch (Exception e) { 214 | JOptionPane.showMessageDialog(UpdaterImpl.this, e.getMessage(), "Missing library", 215 | JOptionPane.ERROR_MESSAGE); 216 | } 217 | } 218 | 219 | @Override 220 | protected void updateFirmware() { 221 | BoardPort port = getSelectedPort(); 222 | if (port == null) { 223 | JOptionPane.showMessageDialog(UpdaterImpl.this, "Please select a port to update firmware!"); 224 | return; 225 | } 226 | 227 | Flasher fw = (Flasher) getFirmwareSelector().getSelectedItem(); 228 | fw.setProgressBar(getUpdateProgressBar()); 229 | setEnabled(false); 230 | new Thread() { 231 | @Override 232 | public void run() { 233 | try { 234 | fw.updateFirmware(port.getAddress()); 235 | JOptionPane.showMessageDialog(UpdaterImpl.this, "The firmware has been updated!", "Success", 236 | JOptionPane.INFORMATION_MESSAGE); 237 | } catch (Exception e) { 238 | e.printStackTrace(); 239 | JOptionPane.showMessageDialog(UpdaterImpl.this, e.getMessage(), "Upload error.", JOptionPane.ERROR_MESSAGE); 240 | } 241 | setEnabled(true); 242 | resetProgress(); 243 | } 244 | }.start(); 245 | } 246 | 247 | @Override 248 | protected void addCertificate() { 249 | String website = JOptionPane.showInputDialog(this, "Enter the website to fetch SSL certificate:", 250 | "Add SSL certificate from website", JOptionPane.QUESTION_MESSAGE); 251 | if (website.startsWith("http://")) { 252 | JOptionPane.showMessageDialog(UpdaterImpl.this, "Sorry \"http://\" protocol doesn't support SSL", 253 | "Invalid URL error.", JOptionPane.ERROR_MESSAGE); 254 | return; 255 | } 256 | if (website.startsWith("https://")) { 257 | website = website.substring(8); 258 | } 259 | if (website.endsWith("/")) { 260 | website = website.substring(0, website.length() - 1); 261 | } 262 | if (!website.contains(":")) { 263 | website += ":443"; 264 | } 265 | if (website.contains("/")) { 266 | JOptionPane.showMessageDialog(UpdaterImpl.this, 267 | "Error: please use enter the addres using the format:\nwww.example.com:443", "Invalid URL error.", 268 | JOptionPane.ERROR_MESSAGE); 269 | return; 270 | } 271 | if (!websites.contains(website)) 272 | websites.add(website); 273 | refreshCertList(); 274 | } 275 | 276 | @Override 277 | protected void removeCertificate() { 278 | int idx = getCertSelector().getSelectedIndex(); 279 | if (idx == -1) 280 | return; 281 | websites.remove(idx); 282 | refreshCertList(); 283 | } 284 | 285 | @Override 286 | protected void uploadCertificates() { 287 | Flasher fw = (Flasher) getFirmwareSelector().getSelectedItem(); 288 | fw.setProgressBar(getUpdateProgressBar()); 289 | BoardPort port = getSelectedPort(); 290 | if (port == null) { 291 | JOptionPane.showMessageDialog(UpdaterImpl.this, "Please select a port to upload SSL certificates!"); 292 | return; 293 | } 294 | 295 | setEnabled(false); 296 | new Thread() { 297 | @SuppressWarnings("synthetic-access") 298 | @Override 299 | public void run() { 300 | try { 301 | fw.uploadCertificates(port.getAddress(), websites); 302 | JOptionPane.showMessageDialog(UpdaterImpl.this, "The certificates have been uploaded!", "Success", 303 | JOptionPane.INFORMATION_MESSAGE); 304 | } catch (Exception e) { 305 | e.printStackTrace(); 306 | JOptionPane.showMessageDialog(UpdaterImpl.this, e.getMessage(), "Upload error.", JOptionPane.ERROR_MESSAGE); 307 | } 308 | setEnabled(true); 309 | resetProgress(); 310 | } 311 | }.start(); 312 | } 313 | 314 | public void resetProgress() { 315 | getUpdateProgressBar().setValue(0); 316 | getUpdateProgressBar().setStringPainted(false); 317 | } 318 | } 319 | -------------------------------------------------------------------------------- /src/cc/arduino/plugins/wifi101/UpdaterJFrame.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WiFi101 Updater Arduino-IDE Plugin. 3 | * Copyright 2016 Arduino LLC (http://www.arduino.cc/) 4 | * 5 | * Arduino is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | * 19 | * As a special exception, you may use this file as part of a free software 20 | * library without restriction. Specifically, if other files instantiate 21 | * templates or use macros or inline functions from this file, or you compile 22 | * this file and link it with other files to produce an executable, this 23 | * file does not by itself cause the resulting executable to be covered by 24 | * the GNU General Public License. This exception does not however 25 | * invalidate any other reasons why the executable file might be covered by 26 | * the GNU General Public License. 27 | */ 28 | package cc.arduino.plugins.wifi101; 29 | 30 | import java.awt.Color; 31 | import java.awt.Dimension; 32 | import java.awt.EventQueue; 33 | import java.awt.GridBagConstraints; 34 | import java.awt.GridBagLayout; 35 | import java.awt.Insets; 36 | import java.awt.event.ActionEvent; 37 | import java.awt.event.ActionListener; 38 | 39 | import javax.swing.JButton; 40 | import javax.swing.JComboBox; 41 | import javax.swing.JFrame; 42 | import javax.swing.JLabel; 43 | import javax.swing.JList; 44 | import javax.swing.JPanel; 45 | import javax.swing.JProgressBar; 46 | import javax.swing.JScrollPane; 47 | import javax.swing.WindowConstants; 48 | import javax.swing.border.EmptyBorder; 49 | import javax.swing.border.LineBorder; 50 | import javax.swing.border.TitledBorder; 51 | import javax.swing.event.ListSelectionEvent; 52 | import javax.swing.event.ListSelectionListener; 53 | 54 | import cc.arduino.plugins.wifi101.flashers.Flasher; 55 | import processing.app.Theme; 56 | 57 | @SuppressWarnings("serial") 58 | public class UpdaterJFrame extends JFrame { 59 | 60 | private JPanel contentPane; 61 | private JList serialPortList; 62 | private JComboBox firmwareSelector; 63 | 64 | private JProgressBar updateProgressBar; 65 | private JButton removeCertificateButton; 66 | private JList certSelector; 67 | private JPanel panel_2; 68 | private JPanel panel; 69 | private JPanel panel_1; 70 | private JLabel textArea; 71 | private JLabel textFwNot; 72 | 73 | private JButton uploadCertificatesButton; 74 | private JButton addCertificateButton; 75 | private JButton updateFirmwareButton; 76 | private JButton testConnectionButton; 77 | private JButton openFirmwareUpdaterSketchButton; 78 | 79 | public static void main(String[] args) { 80 | EventQueue.invokeLater(new Runnable() { 81 | @Override 82 | public void run() { 83 | try { 84 | UpdaterJFrame frame = new UpdaterJFrame(); 85 | frame.setVisible(true); 86 | } catch (Exception e) { 87 | e.printStackTrace(); 88 | } 89 | } 90 | }); 91 | } 92 | 93 | public UpdaterJFrame() { 94 | 95 | int scale = Theme.getScale(); 96 | setTitle("WiFi101 / WiFiNINA Firmware/Certificates Updater"); 97 | setResizable(false); 98 | setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 99 | setBounds(100 * scale / 100, 100 * scale / 100, 500 * scale / 100, 520 * scale / 100); 100 | contentPane = new JPanel(); 101 | contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 102 | setContentPane(contentPane); 103 | GridBagLayout gbl_contentPane = new GridBagLayout(); 104 | gbl_contentPane.columnWidths = new int[]{0, 0}; 105 | gbl_contentPane.rowHeights = new int[]{0, 0, 0, 0, 0}; 106 | gbl_contentPane.columnWeights = new double[]{1.0, Double.MIN_VALUE}; 107 | gbl_contentPane.rowWeights = new double[]{1.0, 1.0, 1.0, 0.0, Double.MIN_VALUE}; 108 | contentPane.setLayout(gbl_contentPane); 109 | 110 | panel_1 = new JPanel(); 111 | panel_1.setBorder(new TitledBorder(null, "1. Select port of the WiFi module", TitledBorder.LEADING, TitledBorder.TOP, null, null)); 112 | panel_1.setMinimumSize(new Dimension(500 * scale / 100, 150 * scale / 100)); 113 | panel_1.setPreferredSize(new Dimension(500 * scale / 100, 150 * scale / 100)); 114 | GridBagConstraints gbc_panel_1 = new GridBagConstraints(); 115 | gbc_panel_1.insets = new Insets(5, 5, 0, 5); 116 | gbc_panel_1.fill = GridBagConstraints.BOTH; 117 | gbc_panel_1.gridx = 0; 118 | gbc_panel_1.gridy = 0; 119 | contentPane.add(panel_1, gbc_panel_1); 120 | GridBagLayout gbl_panel_1 = new GridBagLayout(); 121 | gbl_panel_1.columnWidths = new int[]{0, 0, 0}; 122 | gbl_panel_1.rowHeights = new int[]{0, 0, 0, 0}; 123 | gbl_panel_1.columnWeights = new double[]{1.0, 0.0, Double.MIN_VALUE}; 124 | gbl_panel_1.rowWeights = new double[]{1.0, 1.0, 0.0, Double.MIN_VALUE}; 125 | panel_1.setLayout(gbl_panel_1); 126 | 127 | JLabel textSelectPort = new JLabel("If the port is not listed click \"Refresh list\" button to regenerate the list"); 128 | textSelectPort.setOpaque(false); 129 | GridBagConstraints gbc_textSelectPort = new GridBagConstraints(); 130 | gbc_textSelectPort.fill = GridBagConstraints.HORIZONTAL; 131 | gbc_textSelectPort.gridwidth = 2; 132 | gbc_textSelectPort.insets = new Insets(5, 5, 5, 5); 133 | gbc_textSelectPort.gridx = 0; 134 | gbc_textSelectPort.gridy = 0; 135 | panel_1.add(textSelectPort, gbc_textSelectPort); 136 | 137 | serialPortList = new JList<>(); 138 | JScrollPane sp = new JScrollPane(serialPortList); 139 | serialPortList.setMaximumSize(new Dimension(300 * scale / 100, 100 * scale / 100)); 140 | GridBagConstraints gbc_serialPortList = new GridBagConstraints(); 141 | gbc_serialPortList.insets = new Insets(5, 5, 5, 5); 142 | gbc_serialPortList.fill = GridBagConstraints.BOTH; 143 | gbc_serialPortList.gridx = 0; 144 | gbc_serialPortList.gridy = 1; 145 | gbc_serialPortList.gridheight = 5; 146 | panel_1.add(sp, gbc_serialPortList); 147 | serialPortList.addListSelectionListener(new ListSelectionListener() { 148 | @Override 149 | public void valueChanged(ListSelectionEvent e) { 150 | SelectBoardModule(); 151 | } 152 | }); 153 | 154 | JButton refreshListButton = new JButton("Refresh list"); 155 | refreshListButton.addActionListener(new ActionListener() { 156 | @Override 157 | public void actionPerformed(ActionEvent e) { 158 | refreshSerialPortList(); 159 | } 160 | }); 161 | GridBagConstraints gbc_refreshListButton = new GridBagConstraints(); 162 | gbc_refreshListButton.fill = GridBagConstraints.HORIZONTAL; 163 | gbc_refreshListButton.insets = new Insets(0,0,0,0); 164 | gbc_refreshListButton.gridx = 1; 165 | gbc_refreshListButton.gridy = 2; 166 | panel_1.add(refreshListButton, gbc_refreshListButton); 167 | 168 | testConnectionButton = new JButton("Test connection"); 169 | testConnectionButton.addActionListener(new ActionListener() { 170 | @Override 171 | public void actionPerformed(ActionEvent e) { 172 | testConnection(); 173 | } 174 | }); 175 | 176 | GridBagConstraints gbc_testConnectionButton = new GridBagConstraints(); 177 | gbc_testConnectionButton.insets = new Insets(0,0,0,0); 178 | gbc_testConnectionButton.gridx = 1; 179 | gbc_testConnectionButton.gridy = 3; 180 | panel_1.add(testConnectionButton, gbc_testConnectionButton); 181 | 182 | openFirmwareUpdaterSketchButton = new JButton("Open Updater sketch"); 183 | openFirmwareUpdaterSketchButton.addActionListener(new ActionListener() { 184 | @Override 185 | public void actionPerformed(ActionEvent e) { 186 | openFirmwareUpdaterSketch(); 187 | } 188 | }); 189 | 190 | GridBagConstraints gbc_openFirmwareUpdaterSketchButton = new GridBagConstraints(); 191 | gbc_openFirmwareUpdaterSketchButton.insets = new Insets(0,0,0,0); 192 | gbc_openFirmwareUpdaterSketchButton.gridx = 1; 193 | gbc_openFirmwareUpdaterSketchButton.gridy = 1; 194 | panel_1.add(openFirmwareUpdaterSketchButton, gbc_openFirmwareUpdaterSketchButton); 195 | 196 | panel = new JPanel(); 197 | panel.setBorder(new TitledBorder(new LineBorder(new Color(184, 207, 229)), "2. Update firmware", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(51, 51, 51))); 198 | panel.setMinimumSize(new Dimension(500 * scale / 100, 150 * scale / 100)); 199 | GridBagConstraints gbc_panel = new GridBagConstraints(); 200 | gbc_panel.insets = new Insets(5, 5, 0, 5); 201 | gbc_panel.fill = GridBagConstraints.BOTH; 202 | gbc_panel.gridx = 0; 203 | gbc_panel.gridy = 1; 204 | contentPane.add(panel, gbc_panel); 205 | GridBagLayout gbl_panel = new GridBagLayout(); 206 | gbl_panel.columnWidths = new int[]{0, 0}; 207 | gbl_panel.rowHeights = new int[]{0, 0, 0, 0}; 208 | gbl_panel.columnWeights = new double[]{1.0, Double.MIN_VALUE}; 209 | gbl_panel.rowWeights = new double[]{0.0, 0.0, 0.0, Double.MIN_VALUE}; 210 | panel.setLayout(gbl_panel); 211 | 212 | JLabel textSelectTheFirmware = new JLabel(); 213 | textSelectTheFirmware.setText("Select the firmware from the dropdown box below"); 214 | textSelectTheFirmware.setOpaque(false); 215 | GridBagConstraints gbc_textSelectTheFirmware = new GridBagConstraints(); 216 | gbc_textSelectTheFirmware.insets = new Insets(5, 5, 5, 0); 217 | gbc_textSelectTheFirmware.fill = GridBagConstraints.BOTH; 218 | gbc_textSelectTheFirmware.gridx = 0; 219 | gbc_textSelectTheFirmware.gridy = 1; 220 | panel.add(textSelectTheFirmware, gbc_textSelectTheFirmware); 221 | 222 | firmwareSelector = new JComboBox<>(); 223 | GridBagConstraints gbc_firmwareSelector = new GridBagConstraints(); 224 | gbc_firmwareSelector.insets = new Insets(5, 5, 5, 0); 225 | gbc_firmwareSelector.fill = GridBagConstraints.HORIZONTAL; 226 | gbc_firmwareSelector.gridx = 0; 227 | gbc_firmwareSelector.gridy = 2; 228 | panel.add(firmwareSelector, gbc_firmwareSelector); 229 | 230 | firmwareSelector.addActionListener(new ActionListener() { 231 | @Override 232 | public void actionPerformed(ActionEvent e) { 233 | updateCertSection(); 234 | } 235 | }); 236 | 237 | updateFirmwareButton = new JButton("Update Firmware"); 238 | updateFirmwareButton.addActionListener(new ActionListener() { 239 | @Override 240 | public void actionPerformed(ActionEvent e) { 241 | updateFirmware(); 242 | } 243 | }); 244 | GridBagConstraints gbc_updateFirmwareButton = new GridBagConstraints(); 245 | gbc_updateFirmwareButton.insets = new Insets(5, 5, 0, 0); 246 | gbc_updateFirmwareButton.gridx = 0; 247 | gbc_updateFirmwareButton.gridy = 3; 248 | panel.add(updateFirmwareButton, gbc_updateFirmwareButton); 249 | 250 | panel_2 = new JPanel(); 251 | panel_2.setBorder(new TitledBorder(null, "3. Update SSL root certificates", TitledBorder.LEFT, TitledBorder.TOP, null, null)); 252 | panel_2.setMinimumSize(new Dimension(500 * scale / 100, 200 * scale / 100)); 253 | GridBagConstraints gbc_panel_2 = new GridBagConstraints(); 254 | gbc_panel_2.insets = new Insets(5, 5, 0, 5); 255 | gbc_panel_2.fill = GridBagConstraints.BOTH; 256 | gbc_panel_2.gridx = 0; 257 | gbc_panel_2.gridy = 2; 258 | contentPane.add(panel_2, gbc_panel_2); 259 | GridBagLayout gbl_panel_2 = new GridBagLayout(); 260 | gbl_panel_2.columnWidths = new int[]{0, 0}; 261 | gbl_panel_2.rowHeights = new int[]{0, 0, 0, 0, 0}; 262 | gbl_panel_2.columnWeights = new double[]{1.0, 0.0}; 263 | gbl_panel_2.rowWeights = new double[]{1.0, 1.0, 0.0, 0.0, Double.MIN_VALUE}; 264 | panel_2.setLayout(gbl_panel_2); 265 | 266 | textArea = new JLabel(); 267 | textArea.setText("Add domains in the list below using \"Add domain\" button"); 268 | textArea.setOpaque(false); 269 | GridBagConstraints gbc_textArea = new GridBagConstraints(); 270 | gbc_textArea.gridwidth = 2; 271 | gbc_textArea.insets = new Insets(5, 5, 5, 0); 272 | gbc_textArea.fill = GridBagConstraints.BOTH; 273 | gbc_textArea.gridx = 0; 274 | gbc_textArea.gridy = 0; 275 | panel_2.add(textArea, gbc_textArea); 276 | 277 | textFwNot= new JLabel(); 278 | textFwNot.setText("No certificates available"); 279 | textFwNot.setOpaque(false); 280 | textFwNot.setMinimumSize(new Dimension(500 * scale / 100, 500 * scale / 100)); 281 | GridBagConstraints gbc_textFwNot = new GridBagConstraints(); 282 | gbc_textFwNot.gridwidth = 2; 283 | gbc_textFwNot.insets = new Insets(5, 5, 5, 0); 284 | gbc_textFwNot.fill = GridBagConstraints.BOTH; 285 | gbc_textFwNot.gridx = 0; 286 | gbc_textFwNot.gridy = 0; 287 | panel_2.add(textFwNot, gbc_textFwNot); 288 | textFwNot.setVisible(false); 289 | 290 | certSelector = new JList<>(); 291 | certSelector.addListSelectionListener(new ListSelectionListener() { 292 | @Override 293 | public void valueChanged(ListSelectionEvent e) { 294 | boolean enabled = (getCertSelector().getSelectedIndex() != -1); 295 | getRemoveCertificateButton().setEnabled(enabled); 296 | } 297 | }); 298 | JScrollPane scrollWebsites = new JScrollPane(certSelector); 299 | GridBagConstraints gbc_certSelector = new GridBagConstraints(); 300 | gbc_certSelector.gridheight = 2; 301 | gbc_certSelector.insets = new Insets(0, 0, 5, 5); 302 | gbc_certSelector.fill = GridBagConstraints.BOTH; 303 | gbc_certSelector.gridx = 0; 304 | gbc_certSelector.gridy = 1; 305 | panel_2.add(scrollWebsites, gbc_certSelector); 306 | 307 | addCertificateButton = new JButton("Add domain"); 308 | addCertificateButton.addActionListener(new ActionListener() { 309 | @Override 310 | public void actionPerformed(ActionEvent e) { 311 | addCertificate(); 312 | } 313 | }); 314 | GridBagConstraints gbc_addCertificateButton = new GridBagConstraints(); 315 | gbc_addCertificateButton.insets = new Insets(0, 0, 5, 0); 316 | gbc_addCertificateButton.fill = GridBagConstraints.HORIZONTAL; 317 | gbc_addCertificateButton.gridx = 1; 318 | gbc_addCertificateButton.gridy = 1; 319 | panel_2.add(addCertificateButton, gbc_addCertificateButton); 320 | 321 | removeCertificateButton = new JButton("Remove domain"); 322 | removeCertificateButton.setEnabled(false); 323 | removeCertificateButton.addActionListener(new ActionListener() { 324 | @Override 325 | public void actionPerformed(ActionEvent e) { 326 | removeCertificate(); 327 | } 328 | }); 329 | GridBagConstraints gbc_removeCertificateButton = new GridBagConstraints(); 330 | gbc_removeCertificateButton.insets = new Insets(0, 0, 5, 0); 331 | gbc_removeCertificateButton.fill = GridBagConstraints.HORIZONTAL; 332 | gbc_removeCertificateButton.gridx = 1; 333 | gbc_removeCertificateButton.gridy = 2; 334 | panel_2.add(removeCertificateButton, gbc_removeCertificateButton); 335 | 336 | uploadCertificatesButton = new JButton("Upload Certificates to WiFi module"); 337 | uploadCertificatesButton.addActionListener(new ActionListener() { 338 | @Override 339 | public void actionPerformed(ActionEvent e) { 340 | uploadCertificates(); 341 | } 342 | }); 343 | GridBagConstraints gbc_uploadCertificatesButton = new GridBagConstraints(); 344 | gbc_uploadCertificatesButton.gridwidth = 2; 345 | gbc_uploadCertificatesButton.insets = new Insets(0, 0, 0, 5); 346 | gbc_uploadCertificatesButton.gridx = 0; 347 | gbc_uploadCertificatesButton.gridy = 3; 348 | panel_2.add(uploadCertificatesButton, gbc_uploadCertificatesButton); 349 | 350 | updateProgressBar = new JProgressBar(); 351 | GridBagConstraints gbc_updateProgressBar = new GridBagConstraints(); 352 | gbc_updateProgressBar.insets = new Insets(5, 5, 5, 5); 353 | gbc_updateProgressBar.fill = GridBagConstraints.HORIZONTAL; 354 | gbc_updateProgressBar.gridx = 0; 355 | gbc_updateProgressBar.gridy = 3; 356 | contentPane.add(updateProgressBar, gbc_updateProgressBar); 357 | } 358 | 359 | protected void hideCertificatePanel(boolean visible){ 360 | panel_2.setEnabled(visible); 361 | certSelector.setVisible(visible); 362 | uploadCertificatesButton.setVisible(visible); 363 | addCertificateButton.setVisible(visible); 364 | removeCertificateButton.setVisible(visible); 365 | textArea.setVisible(visible); 366 | textFwNot.setVisible(!visible); 367 | } 368 | 369 | protected void setEnabledCommand(boolean state) { 370 | uploadCertificatesButton.setEnabled(state); 371 | addCertificateButton.setEnabled(state); 372 | testConnectionButton.setEnabled(state); 373 | updateFirmwareButton.setEnabled(state); 374 | firmwareSelector.setEnabled(state); 375 | certSelector.setEnabled(state); 376 | } 377 | 378 | protected void uploadCertificates() { 379 | // To be overridden 380 | } 381 | 382 | protected void removeCertificate() { 383 | // To be overridden 384 | } 385 | 386 | protected void addCertificate() { 387 | // To be overridden 388 | } 389 | 390 | protected void updateFirmware() { 391 | // To be overridden 392 | } 393 | 394 | protected void testConnection() { 395 | // To be overridden 396 | } 397 | 398 | protected void openFirmwareUpdaterSketch() { 399 | // To be overridden 400 | } 401 | 402 | protected void refreshSerialPortList() { 403 | // To be overridden 404 | } 405 | 406 | protected void SelectBoardModule() { 407 | // To be overridden 408 | } 409 | 410 | protected void updateCertSection() { 411 | // To be overridden 412 | } 413 | 414 | protected JList getSerialPortList() { 415 | return serialPortList; 416 | } 417 | protected JComboBox getFirmwareSelector() { 418 | return firmwareSelector; 419 | } 420 | protected JProgressBar getUpdateProgressBar() { 421 | return updateProgressBar; 422 | } 423 | protected JButton getRemoveCertificateButton() { 424 | return removeCertificateButton; 425 | } 426 | protected JList getCertSelector() { 427 | return certSelector; 428 | } 429 | } 430 | -------------------------------------------------------------------------------- /src/cc/arduino/plugins/wifi101/WiFi101.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WiFi101 Updater Arduino-IDE Plugin. 3 | * Copyright 2016 Arduino LLC (http://www.arduino.cc/) 4 | * 5 | * Arduino is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | * 19 | * As a special exception, you may use this file as part of a free software 20 | * library without restriction. Specifically, if other files instantiate 21 | * templates or use macros or inline functions from this file, or you compile 22 | * this file and link it with other files to produce an executable, this 23 | * file does not by itself cause the resulting executable to be covered by 24 | * the GNU General Public License. This exception does not however 25 | * invalidate any other reasons why the executable file might be covered by 26 | * the GNU General Public License. 27 | */ 28 | package cc.arduino.plugins.wifi101; 29 | 30 | import processing.app.Editor; 31 | import processing.app.tools.Tool; 32 | 33 | public class WiFi101 implements Tool { 34 | Editor editor; 35 | 36 | UpdaterImpl updater; 37 | 38 | @Override 39 | public void init(Editor _editor) { 40 | this.editor = _editor; 41 | } 42 | 43 | @Override 44 | public String getMenuTitle() { 45 | return "WiFi101 / WiFiNINA Firmware Updater"; 46 | } 47 | 48 | @Override 49 | public synchronized void run() { 50 | if (updater == null) 51 | try { 52 | updater = new UpdaterImpl(); 53 | } catch (Exception e) { 54 | e.printStackTrace(); 55 | // Failed to open tool 56 | return; 57 | } 58 | updater.setVisible(true); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/cc/arduino/plugins/wifi101/certs/WiFi101Certificate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WiFi101 Updater Arduino-IDE Plugin. 3 | * Copyright 2016 Arduino LLC (http://www.arduino.cc/) 4 | * 5 | * Arduino is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | * 19 | * As a special exception, you may use this file as part of a free software 20 | * library without restriction. Specifically, if other files instantiate 21 | * templates or use macros or inline functions from this file, or you compile 22 | * this file and link it with other files to produce an executable, this 23 | * file does not by itself cause the resulting executable to be covered by 24 | * the GNU General Public License. This exception does not however 25 | * invalidate any other reasons why the executable file might be covered by 26 | * the GNU General Public License. 27 | */ 28 | package cc.arduino.plugins.wifi101.certs; 29 | 30 | import java.io.ByteArrayOutputStream; 31 | import java.io.IOException; 32 | import java.security.MessageDigest; 33 | import java.security.NoSuchAlgorithmException; 34 | import java.security.cert.X509Certificate; 35 | import java.security.interfaces.RSAPublicKey; 36 | import java.util.Arrays; 37 | import java.util.Calendar; 38 | import java.util.Date; 39 | import java.util.TimeZone; 40 | 41 | import org.apache.commons.codec.binary.Hex; 42 | import org.bouncycastle.asn1.ASN1Encodable; 43 | import org.bouncycastle.asn1.ASN1InputStream; 44 | import org.bouncycastle.asn1.ASN1OutputStream; 45 | import org.bouncycastle.asn1.ASN1Primitive; 46 | import org.bouncycastle.asn1.DERPrintableString; 47 | import org.bouncycastle.asn1.DERUTF8String; 48 | import org.bouncycastle.asn1.DLSequence; 49 | import org.bouncycastle.asn1.DLSet; 50 | import org.bouncycastle.asn1.x509.Time; 51 | 52 | public class WiFi101Certificate { 53 | 54 | byte v0Data[]; 55 | byte v1Data[]; 56 | String subject; 57 | String hash; 58 | 59 | public WiFi101Certificate(X509Certificate x509) throws Exception, NoSuchAlgorithmException, IOException { 60 | String algo = x509.getPublicKey().getAlgorithm(); 61 | if (!algo.equals("RSA") || !(x509.getPublicKey() instanceof RSAPublicKey)) 62 | throw new Exception("SSL Certificate must have an RSA Public Key"); 63 | RSAPublicKey publicKey = (RSAPublicKey) x509.getPublicKey(); 64 | 65 | byte[] publicExponent = publicKey.getPublicExponent().toByteArray(); 66 | byte[] publicExponentLen = shortToBytes(publicExponent.length); 67 | byte[] publicModulus = publicKey.getModulus().toByteArray(); 68 | if (publicModulus.length == 257 || publicModulus[0] == 0) { 69 | publicModulus = Arrays.copyOfRange(publicModulus, 1, publicModulus.length); 70 | } 71 | byte[] publicModulusLen = shortToBytes(publicModulus.length); 72 | byte[] name1hash = getSubjectValueHash(x509); 73 | byte[] notBeforeV0 = encodeTimestampV0(x509.getNotBefore()); 74 | byte[] notAfterV0 = encodeTimestampV0(x509.getNotAfter()); 75 | byte[] notBeforeV1 = encodeTimestampV1(x509.getNotBefore()); 76 | byte[] notAfterV1 = encodeTimestampV1(x509.getNotAfter()); 77 | byte[] type = {0x01, 0x00, 0x00, 0x00}; // for RSA 78 | 79 | ByteArrayOutputStream v0Res = new ByteArrayOutputStream(); 80 | v0Res.write(name1hash); 81 | v0Res.write(publicModulusLen); 82 | v0Res.write(publicExponentLen); 83 | v0Res.write(notBeforeV0); 84 | v0Res.write(notAfterV0); 85 | v0Res.write(publicModulus); 86 | v0Res.write(publicExponent); 87 | while (v0Res.size() % 4 != 0) 88 | v0Res.write(0xFF); 89 | v0Data = v0Res.toByteArray(); 90 | 91 | ByteArrayOutputStream v1Res = new ByteArrayOutputStream(); 92 | v1Res.write(name1hash); 93 | v1Res.write(notBeforeV1); 94 | v1Res.write(notAfterV1); 95 | v1Res.write(type); 96 | v1Res.write(publicModulusLen); 97 | v1Res.write(publicExponentLen); 98 | v1Res.write(publicModulus); 99 | v1Res.write(publicExponent); 100 | while (v1Res.size() % 4 != 0) 101 | v1Res.write(0xFF); 102 | v1Data = v1Res.toByteArray(); 103 | 104 | byte[] digest = MessageDigest.getInstance("SHA-1").digest(v0Data); 105 | hash = Hex.encodeHexString(digest).substring(0, 6); 106 | } 107 | 108 | @Override 109 | public String toString() { 110 | return "(" + hash + ")"; 111 | } 112 | 113 | private static byte[] shortToBytes(int x) { 114 | // little endian 115 | byte ret[] = new byte[2]; 116 | ret[0] = (byte) x; 117 | ret[1] = (byte) (x >> 8); 118 | return ret; 119 | } 120 | 121 | private static byte[] encodeTimestampV0(Date notBefore) throws IOException { 122 | ByteArrayOutputStream encoded = new ByteArrayOutputStream(); 123 | ASN1OutputStream asn1 = new ASN1OutputStream(encoded); 124 | asn1.writeObject(new Time(notBefore)); 125 | return Arrays.copyOfRange(encoded.toByteArray(), 2, 22); 126 | } 127 | 128 | private static byte[] encodeTimestampV1(Date timestamp) throws IOException { 129 | ByteArrayOutputStream encoded = new ByteArrayOutputStream(); 130 | 131 | TimeZone timeZone = TimeZone.getTimeZone("UTC"); 132 | Calendar cal = Calendar.getInstance(timeZone); 133 | cal.setTime(timestamp); 134 | 135 | int year = cal.get(Calendar.YEAR); 136 | int month = cal.get(Calendar.MONTH) + 1; 137 | int day = cal.get(Calendar.DAY_OF_MONTH); 138 | int hour = cal.get(Calendar.HOUR_OF_DAY); 139 | int minutes = cal.get(Calendar.MINUTE); 140 | int seconds = cal.get(Calendar.SECOND); 141 | 142 | encoded.write((byte)(year & 0xff)); 143 | encoded.write((byte)((year >> 8) & 0xff)); 144 | encoded.write((byte)(month)); 145 | encoded.write((byte)(day)); 146 | encoded.write((byte)(hour)); 147 | encoded.write((byte)(minutes)); 148 | encoded.write((byte)(seconds)); 149 | encoded.write((byte)(0xcc)); 150 | 151 | return encoded.toByteArray(); 152 | } 153 | 154 | private static byte[] getSubjectValueHash(X509Certificate x509) throws NoSuchAlgorithmException, IOException { 155 | MessageDigest sha1 = MessageDigest.getInstance("SHA-1"); 156 | try (ASN1InputStream ais = new ASN1InputStream(x509.getSubjectX500Principal().getEncoded())) { 157 | while (ais.available() > 0) { 158 | ASN1Primitive obj = ais.readObject(); 159 | sha1.update(extractPrintableString(obj)); 160 | } 161 | } 162 | return sha1.digest(); 163 | } 164 | 165 | private static byte[] extractPrintableString(ASN1Encodable obj) throws IOException { 166 | if (obj instanceof DERPrintableString) { 167 | DERPrintableString s = (DERPrintableString) obj; 168 | return s.getString().getBytes(); 169 | } else if (obj instanceof DERUTF8String) { 170 | DERUTF8String s = (DERUTF8String) obj; 171 | return s.getString().getBytes(); 172 | } 173 | 174 | ByteArrayOutputStream res = new ByteArrayOutputStream(); 175 | if (obj instanceof DLSequence) { 176 | DLSequence s = (DLSequence) obj; 177 | for (int i = 0; i < s.size(); i++) { 178 | res.write(extractPrintableString(s.getObjectAt(i))); 179 | } 180 | } 181 | if (obj instanceof DLSet) { 182 | DLSet s = (DLSet) obj; 183 | for (int i = 0; i < s.size(); i++) { 184 | res.write(extractPrintableString(s.getObjectAt(i))); 185 | } 186 | } 187 | return res.toByteArray(); 188 | } 189 | 190 | public byte[] getEncodedV0() { 191 | return v0Data.clone(); 192 | } 193 | 194 | public byte[] getEncodedV1() { 195 | return v1Data.clone(); 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /src/cc/arduino/plugins/wifi101/certs/WiFi101CertificateBundle.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WiFi101 Updater Arduino-IDE Plugin. 3 | * Copyright 2016 Arduino LLC (http://www.arduino.cc/) 4 | * 5 | * Arduino is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | * 19 | * As a special exception, you may use this file as part of a free software 20 | * library without restriction. Specifically, if other files instantiate 21 | * templates or use macros or inline functions from this file, or you compile 22 | * this file and link it with other files to produce an executable, this 23 | * file does not by itself cause the resulting executable to be covered by 24 | * the GNU General Public License. This exception does not however 25 | * invalidate any other reasons why the executable file might be covered by 26 | * the GNU General Public License. 27 | */ 28 | package cc.arduino.plugins.wifi101.certs; 29 | 30 | import java.io.ByteArrayOutputStream; 31 | import java.io.IOException; 32 | import java.util.ArrayList; 33 | 34 | @SuppressWarnings("serial") 35 | public class WiFi101CertificateBundle extends ArrayList { 36 | 37 | public static final byte START_PATTERN_V0[] = new byte[] { 0x01, (byte) 0xF1, 0x02, (byte) 0xF2, 0x03, (byte) 0xF3, 0x04, 38 | (byte) 0xF4, 0x05, (byte) 0xF5, 0x06, (byte) 0xF6, 0x07, (byte) 0xF7, 0x08, (byte) 0xF8 }; 39 | 40 | public static final byte START_PATTERN_V1[] = new byte[] { 0x11, (byte) 0xF1, 0x12, (byte) 0xF2, 0x13, (byte) 0xF3, 0x14, 41 | (byte) 0xF4, 0x15, (byte) 0xF5, 0x16, (byte) 0xF6, 0x17, (byte) 0xF7, 0x18, (byte) 0xF8 }; 42 | 43 | public byte[] getEncodedV0() { 44 | ByteArrayOutputStream res = new ByteArrayOutputStream(); 45 | try { 46 | res.write(START_PATTERN_V0); 47 | 48 | // Write number of certs, little endian 49 | res.write(size()); 50 | res.write(0); 51 | res.write(0); 52 | res.write(0); 53 | 54 | for (WiFi101Certificate cert : this) { 55 | res.write(cert.getEncodedV0()); 56 | } 57 | } catch (IOException e) { 58 | // Should never happen... 59 | e.printStackTrace(); 60 | return null; 61 | } 62 | return res.toByteArray(); 63 | } 64 | 65 | public byte[] getEncodedV1() { 66 | ByteArrayOutputStream res = new ByteArrayOutputStream(); 67 | try { 68 | res.write(START_PATTERN_V1); 69 | 70 | // Write number of certs, little endian 71 | res.write(size()); 72 | res.write(0); 73 | res.write(0); 74 | res.write(0); 75 | 76 | for (WiFi101Certificate cert : this) { 77 | res.write(cert.getEncodedV1()); 78 | } 79 | } catch (IOException e) { 80 | // Should never happen... 81 | e.printStackTrace(); 82 | return null; 83 | } 84 | return res.toByteArray(); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/cc/arduino/plugins/wifi101/flashers/Flasher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WiFi101 Updater Arduino-IDE Plugin. 3 | * Copyright 2016 Arduino LLC (http://www.arduino.cc/) 4 | * 5 | * Arduino is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | * 19 | * As a special exception, you may use this file as part of a free software 20 | * library without restriction. Specifically, if other files instantiate 21 | * templates or use macros or inline functions from this file, or you compile 22 | * this file and link it with other files to produce an executable, this 23 | * file does not by itself cause the resulting executable to be covered by 24 | * the GNU General Public License. This exception does not however 25 | * invalidate any other reasons why the executable file might be covered by 26 | * the GNU General Public License. 27 | */ 28 | package cc.arduino.plugins.wifi101.flashers; 29 | 30 | import java.io.ByteArrayOutputStream; 31 | import java.io.File; 32 | import java.io.FileInputStream; 33 | import java.io.IOException; 34 | import java.io.InputStream; 35 | import java.net.URISyntaxException; 36 | import java.util.ArrayList; 37 | import java.util.List; 38 | 39 | import javax.swing.JProgressBar; 40 | 41 | import org.apache.commons.lang3.StringUtils; 42 | 43 | import cc.arduino.packages.BoardPort; 44 | import cc.arduino.plugins.wifi101.flashers.java.FlasherSerialClient; 45 | import processing.app.Base; 46 | import processing.app.BaseNoGui; 47 | import processing.app.packages.LibraryList; 48 | import processing.app.packages.UserLibrary; 49 | 50 | public class Flasher { 51 | 52 | public String modulename; 53 | public String version; 54 | public File file; 55 | public JProgressBar progressBar; 56 | public String name; 57 | public String filename; 58 | public List compatibleBoards; 59 | public boolean certavail; 60 | protected int baudrate; 61 | 62 | public Flasher() {} 63 | 64 | public Flasher(String _modulename, String _version, String _filename, boolean _certavail, int _baudrate, List _compatibleBoards) { 65 | modulename = _modulename; 66 | compatibleBoards = new ArrayList<>(_compatibleBoards); 67 | version = _version; 68 | file = null; 69 | name = "NINA"; 70 | certavail = _certavail; 71 | filename = _filename; 72 | baudrate = _baudrate; 73 | } 74 | 75 | public void progress(int progress, String text) { 76 | if (text.length() > 60) { 77 | text = text.substring(0, 60) + "..."; 78 | } 79 | progressBar.setValue(progress); 80 | progressBar.setStringPainted(true); 81 | progressBar.setString(text); 82 | } 83 | 84 | public void testConnection(String port, int baud) throws Exception { 85 | FlasherSerialClient client = null; 86 | try { 87 | progress(50, "Testing programmer..."); 88 | client = new FlasherSerialClient(); 89 | client.open(port, baud); 90 | client.hello(); 91 | progress(100, "Done!"); 92 | } finally { 93 | if (client != null) { 94 | client.close(); 95 | } 96 | } 97 | } 98 | 99 | public void openFirmwareUpdaterSketch(BoardPort port) throws Exception { 100 | LibraryList allLibraries = BaseNoGui.librariesIndexer.getInstalledLibraries(); 101 | String firmwareUpdaterExamplePath = ""; 102 | String nameToSearchFor = ""; 103 | String pathToSketch = ""; 104 | if (modulename.contains("NINA")) { 105 | nameToSearchFor = "WiFiNINA"; 106 | pathToSketch = "examples/Tools/FirmwareUpdater/FirmwareUpdater.ino"; 107 | } 108 | if (modulename.contains("WINC")) { 109 | nameToSearchFor = "WiFi101"; 110 | pathToSketch = "examples/FirmwareUpdater/FirmwareUpdater.ino"; 111 | } 112 | for (UserLibrary lib : allLibraries) { 113 | if (lib.getName().equals(nameToSearchFor)) { 114 | firmwareUpdaterExamplePath = lib.getInstalledFolder().getAbsolutePath() + "/" + pathToSketch; 115 | } 116 | } 117 | if (firmwareUpdaterExamplePath == "") { 118 | String errorMessage = nameToSearchFor + "library"; 119 | if (port.getBoardName() != "") { 120 | errorMessage += " for " + port.getBoardName(); 121 | } 122 | errorMessage += " is not installed.\nUse the library manager to install it."; 123 | throw new Exception(errorMessage); 124 | } 125 | 126 | if (firmwareUpdaterExamplePath != "" && port != null) { 127 | BaseNoGui.selectSerialPort(port.getAddress()); 128 | Base.INSTANCE.onBoardOrPortChange(); 129 | Base.INSTANCE.handleOpen(new File(firmwareUpdaterExamplePath)); 130 | } 131 | } 132 | 133 | public void updateFirmware(String port) throws Exception { 134 | // To be overridden 135 | } 136 | 137 | public void uploadCertificates(String port, List websites) throws Exception { 138 | // To be overridden 139 | } 140 | 141 | public void setProgressBar(JProgressBar _progressBar) { 142 | progressBar = _progressBar; 143 | } 144 | 145 | public String getName() { 146 | return name; 147 | } 148 | 149 | public int getBaudrate() { 150 | return baudrate; 151 | } 152 | 153 | public byte[] getData() throws IOException { 154 | InputStream in = null; 155 | try { 156 | in = new FileInputStream(file); 157 | ByteArrayOutputStream res = new ByteArrayOutputStream(); 158 | byte buff[] = new byte[4096]; 159 | while (in.available() > 0) { 160 | int read = in.read(buff); 161 | if (read == -1) { 162 | break; 163 | } 164 | res.write(buff, 0, read); 165 | } 166 | return res.toByteArray(); 167 | } finally { 168 | if (in != null) { 169 | in.close(); 170 | } 171 | } 172 | } 173 | 174 | public File getFile() { 175 | return file; 176 | } 177 | 178 | public void setFileName(String _filename) { 179 | filename = _filename; 180 | } 181 | 182 | public boolean isCompatible(String boardName) { 183 | if (boardName == null) { 184 | return false; 185 | } 186 | for (String compatibleBoard : compatibleBoards) { 187 | if (compatibleBoard.equalsIgnoreCase(boardName)) { 188 | return true; 189 | } 190 | } 191 | return false; 192 | } 193 | 194 | public boolean certificatesAvailable() { 195 | return certavail; 196 | } 197 | 198 | public File openFirmwareFile() throws Exception { 199 | try { 200 | String jarPath = Flasher.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath(); 201 | File jarFolder = new File(jarPath).getParentFile(); 202 | File fwfile = new File(jarFolder, filename); 203 | return fwfile; 204 | } catch (URISyntaxException e) { 205 | String message = "File not found "; 206 | throw new Exception(message.concat(filename)); 207 | } 208 | } 209 | 210 | @Override 211 | public String toString() { 212 | String names = modulename + " (" + version + ") ("; 213 | for (String lname : compatibleBoards) { 214 | names = names.concat(lname).concat(", "); 215 | } 216 | names = names.substring(0, (names.length() - 2)).concat(")"); 217 | names = StringUtils.abbreviate(names, 75); 218 | return names; 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /src/cc/arduino/plugins/wifi101/flashers/java/FlasherSerialClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WiFi101 Updater Arduino-IDE Plugin. 3 | * Copyright 2016 Arduino LLC (http://www.arduino.cc/) 4 | * 5 | * Arduino is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | * 19 | * As a special exception, you may use this file as part of a free software 20 | * library without restriction. Specifically, if other files instantiate 21 | * templates or use macros or inline functions from this file, or you compile 22 | * this file and link it with other files to produce an executable, this 23 | * file does not by itself cause the resulting executable to be covered by 24 | * the GNU General Public License. This exception does not however 25 | * invalidate any other reasons why the executable file might be covered by 26 | * the GNU General Public License. 27 | */ 28 | package cc.arduino.plugins.wifi101.flashers.java; 29 | 30 | import static jssc.SerialPort.PARITY_NONE; 31 | import static jssc.SerialPort.STOPBITS_1; 32 | import static processing.app.I18n.format; 33 | import static processing.app.I18n.tr; 34 | 35 | import java.io.ByteArrayOutputStream; 36 | import java.nio.ByteBuffer; 37 | import java.nio.ByteOrder; 38 | 39 | import jssc.SerialPort; 40 | import jssc.SerialPortException; 41 | import processing.app.SerialException; 42 | import processing.app.SerialNotFoundException; 43 | 44 | public class FlasherSerialClient { 45 | 46 | private SerialPort port; 47 | private volatile byte recvBuffer[] = new byte[1000000]; 48 | private volatile int recvPos = 0, writePos = 0; 49 | 50 | public void open(String portName, int baudrate) throws SerialException, InterruptedException { 51 | try { 52 | port = new SerialPort(portName); 53 | if (!port.openPort()) { 54 | throw new SerialException("Error opening serial port"); 55 | } 56 | boolean res = port.setParams(baudrate, 8, STOPBITS_1, PARITY_NONE, true, true); 57 | if (!res) { 58 | System.err.println(format(tr("Error while setting serial port parameters: {0} {1} {2} {3}"), 115200, 59 | PARITY_NONE, 8, STOPBITS_1)); 60 | } 61 | port.addEventListener((evt) -> { 62 | if (!evt.isRXCHAR()) 63 | return; 64 | try { 65 | byte[] data = port.readBytes(evt.getEventValue()); 66 | // System.out.println("READ: " + data.length); 67 | if (data == null || data.length == 0) 68 | return; 69 | synchronized (recvBuffer) { 70 | for (int i = 0; i < data.length; i++) 71 | recvBuffer[writePos++] = data[i]; 72 | } 73 | } catch (Exception e) { 74 | e.printStackTrace(); 75 | return; 76 | } 77 | }); 78 | } catch (SerialPortException e) { 79 | if (e.getPortName().startsWith("/dev") 80 | && SerialPortException.TYPE_PERMISSION_DENIED.equals(e.getExceptionType())) { 81 | throw new SerialException(format( 82 | tr("Error opening serial port ''{0}''. Try consulting the documentation at http://playground.arduino.cc/Linux/All#Permission"), 83 | portName)); 84 | } 85 | throw new SerialException(format(tr("Error opening serial port ''{0}''."), portName), e); 86 | } 87 | 88 | if (port == null) { 89 | throw new SerialNotFoundException(format(tr("Serial port ''{0}'' not found."), portName)); 90 | } 91 | 92 | // Wait for boards that do auto-reset on serial port opening 93 | Thread.sleep(2500); 94 | } 95 | 96 | public void close() throws SerialException { 97 | try { 98 | port.closePort(); 99 | } catch (Exception e) { 100 | throw new SerialException(format(tr("Error opening serial port.\nClose the serial monitor (if open) or any program using port '{0}'"), port.getPortName())); 101 | } 102 | } 103 | 104 | public void hello() throws Exception { 105 | sendCommand((byte) 0x99, 0x11223344, 0x55667788, null); 106 | byte[] answer = waitAnswer(2000, 6, true); 107 | if (answer.length != 6 || answer[0] != 'v') { 108 | throw new Exception("Programmer not responding\nMake sure that FirmwareUpdater sketch is loaded on the board."); 109 | } 110 | String version = new String(answer); 111 | if (!version.equals("v10000")) 112 | throw new Exception("Programmer version mismatch: " + version + ", but v10000 is required!"); 113 | } 114 | 115 | public int getMaximumPayload() throws Exception { 116 | sendCommand((byte) 0x50, 0, 0, null); 117 | byte[] answer = waitAnswer(100, 2); 118 | if (answer.length != 2) 119 | throw new Exception("Error while reading programmers parameters."); 120 | return answer[0] << 8 + answer[1]; 121 | } 122 | 123 | public byte[] readFlash(int address, int length) throws Exception { 124 | sendCommand((byte) 0x01, address, length, null); 125 | byte[] data = waitAnswer(500, length); 126 | if (data.length != length) { 127 | throw new Exception("Error while reading flash memory."); 128 | } 129 | if (!ack()) 130 | throw new Exception("Error while reading flash memory."); 131 | return data; 132 | } 133 | 134 | public byte[] md5Flash(int address, int length) throws Exception { 135 | sendCommand((byte) 0x04, address, length, null); 136 | if (ack(10000)) { 137 | byte[] data = waitAnswer(10000, 16); 138 | return data; 139 | } 140 | return null; 141 | } 142 | 143 | public void writeFlash(int address, byte data[]) throws Exception { 144 | sendCommand((byte) 0x02, address, 0, data); 145 | if (!ack()) 146 | throw new Exception("Error while writing flash memory."); 147 | } 148 | 149 | public void eraseFlash(int address, int size) throws Exception { 150 | sendCommand((byte) 0x03, address, size, null); 151 | if (!ack(20000)) 152 | throw new Exception("Error while erasing flash memory."); 153 | } 154 | 155 | public void addCertificateHighLevel(int command, byte payload[]) throws Exception { 156 | sendCommand((byte) 0x55, command, command, payload); 157 | if (!ack(20000)) 158 | throw new Exception("Error while uploading certificate."); 159 | } 160 | 161 | private boolean ack() throws InterruptedException { 162 | return ack(1000); 163 | } 164 | 165 | private boolean ack(int timeout) throws InterruptedException { 166 | byte[] ack = waitAnswer(timeout, 2); 167 | if (ack.length != 2 || ack[0] != 'O' || ack[1] != 'K') 168 | return false; 169 | return true; 170 | } 171 | 172 | private byte[] waitAnswer(int timeout, int expectedLen) throws InterruptedException { 173 | return waitAnswer(timeout, expectedLen, false); 174 | } 175 | 176 | private byte[] waitAnswer(int timeout, int expectedLen, boolean asciionly) throws InterruptedException { 177 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 178 | int written = 0; 179 | while (timeout > 0 && written < expectedLen) { 180 | int c = read(); 181 | if (c != -1 && (!asciionly || (c > 0 && c < 128))) { 182 | out.write(c); 183 | written++; 184 | continue; 185 | } 186 | Thread.sleep(10); 187 | timeout -= 10; 188 | } 189 | return out.toByteArray(); 190 | } 191 | 192 | private int read() { 193 | synchronized (recvBuffer) { 194 | if (recvPos == writePos) 195 | return -1; 196 | return recvBuffer[recvPos++] & 0xFF; 197 | } 198 | } 199 | 200 | private void sendCommand(byte command, int address, int val, byte payload[]) throws SerialPortException { 201 | short payloadLen = 0; 202 | if (payload != null) 203 | payloadLen = (short) payload.length; 204 | ByteBuffer buff = ByteBuffer.allocate(11 + payloadLen); 205 | buff.order(ByteOrder.BIG_ENDIAN); 206 | buff.put(command); 207 | buff.putInt(address); 208 | buff.putInt(val); 209 | buff.putShort(payloadLen); 210 | if (payload != null) 211 | buff.put(payload); 212 | byte data[] = buff.array(); 213 | // System.out.println("CMD:" + DatatypeConverter.printHexBinary(data)); 214 | port.writeBytes(data); 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /src/cc/arduino/plugins/wifi101/flashers/java/NinaFlasher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WiFi101 Updater Arduino-IDE Plugin. 3 | * Copyright 2016 Arduino LLC (http://www.arduino.cc/) 4 | * 5 | * Arduino is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | * 19 | * As a special exception, you may use this file as part of a free software 20 | * library without restriction. Specifically, if other files instantiate 21 | * templates or use macros or inline functions from this file, or you compile 22 | * this file and link it with other files to produce an executable, this 23 | * file does not by itself cause the resulting executable to be covered by 24 | * the GNU General Public License. This exception does not however 25 | * invalidate any other reasons why the executable file might be covered by 26 | * the GNU General Public License. 27 | */ 28 | package cc.arduino.plugins.wifi101.flashers.java; 29 | 30 | import java.io.ByteArrayOutputStream; 31 | import java.net.MalformedURLException; 32 | import java.net.URL; 33 | import java.security.MessageDigest; 34 | import java.security.cert.Certificate; 35 | import java.security.cert.X509Certificate; 36 | import java.util.Arrays; 37 | import java.util.List; 38 | 39 | import org.apache.commons.codec.binary.Base64; 40 | 41 | import cc.arduino.plugins.wifi101.flashers.Flasher; 42 | 43 | public class NinaFlasher extends Flasher { 44 | 45 | public byte[] md5Checksum; 46 | 47 | public NinaFlasher(String _modulename, String _version, String _filename, boolean _certavail, int _baudrate, List _compatibleBoard) { 48 | super(_modulename, _version, _filename, _certavail, _baudrate, _compatibleBoard); 49 | } 50 | 51 | @Override 52 | public void updateFirmware(String port) throws Exception { 53 | FlasherSerialClient client = null; 54 | try { 55 | file = openFirmwareFile(); 56 | progress(10, "Connecting to programmer..."); 57 | client = new FlasherSerialClient(); 58 | client.open(port, this.baudrate); 59 | client.hello(); 60 | int maxPayload = client.getMaximumPayload(); 61 | 62 | byte[] fwData = this.getData(); 63 | int size = fwData.length; 64 | int address = 0x00000000; 65 | int written = 0; 66 | 67 | progress(20, "Erasing target..."); 68 | 69 | client.eraseFlash(address, size); 70 | 71 | while (written < size) { 72 | progress(20 + written * 40 / size, "Programming " + size + " bytes ..."); 73 | int len = maxPayload; 74 | if (written + len > size) { 75 | len = size - written; 76 | } 77 | client.writeFlash(address, Arrays.copyOfRange(fwData, written, written + len)); 78 | written += len; 79 | address += len; 80 | } 81 | 82 | progress(55, "Verifying..."); 83 | 84 | md5Checksum = getMD5Checksum(fwData); 85 | 86 | address = 0x00000000; 87 | byte[] md5rec = client.md5Flash(address, size); 88 | progress(75, "Verifying..."); 89 | if (Arrays.equals(md5rec, md5Checksum)) { 90 | progress(100, "Done!"); 91 | } else { 92 | throw new Exception("Error validating flashed firmware"); 93 | } 94 | } finally { 95 | if (client != null) { 96 | client.close(); 97 | } 98 | } 99 | } 100 | 101 | @Override 102 | public void uploadCertificates(String port, List websites) throws Exception { 103 | FlasherSerialClient client = null; 104 | try { 105 | file = openFirmwareFile(); 106 | progress(10, "Connecting to programmer..."); 107 | client = new FlasherSerialClient(); 108 | client.open(port, this.baudrate); 109 | client.hello(); 110 | int maxPayload = client.getMaximumPayload(); 111 | int count = websites.size(); 112 | String pem = ""; 113 | 114 | for (String website : websites) { 115 | URL url; 116 | try { 117 | url = new URL(website); 118 | } catch (MalformedURLException e1) { 119 | url = new URL("https://" + website); 120 | } 121 | 122 | progress(30 + 20 * count / websites.size(), "Downloading certificate from " + website + "..."); 123 | Certificate[] certificates = SSLCertDownloader.retrieveFromURL(url); 124 | 125 | // Pick the latest certificate (that should be the root cert) 126 | X509Certificate x509 = (X509Certificate) certificates[certificates.length - 1]; 127 | pem = convertToPem(x509) + "\n" + pem; 128 | } 129 | 130 | byte[] pemArray = pem.getBytes(); 131 | ByteArrayOutputStream output = new ByteArrayOutputStream(); 132 | output.write(pemArray); 133 | while (output.size() % maxPayload != 0) { 134 | output.write(0); 135 | } 136 | byte[] fwData = output.toByteArray(); 137 | 138 | int size = fwData.length; 139 | int address = 0x10000; 140 | int written = 0; 141 | 142 | if (size > 0x20000) { 143 | throw new Exception("Too many certificates!"); 144 | } 145 | 146 | progress(20, "Erasing target..."); 147 | 148 | client.eraseFlash(address, size); 149 | 150 | while (written < size) { 151 | progress(20 + written * 40 / size, "Programming " + size + " bytes ..."); 152 | int len = maxPayload; 153 | if (written + len > size) { 154 | len = size - written; 155 | } 156 | client.writeFlash(address, Arrays.copyOfRange(fwData, written, written + len)); 157 | written += len; 158 | address += len; 159 | } 160 | } finally { 161 | if (client != null) { 162 | client.close(); 163 | } 164 | } 165 | } 166 | 167 | protected static String convertToPem(X509Certificate cert) { 168 | Base64 encoder = new Base64(64, "\n".getBytes()); 169 | String cert_begin = "-----BEGIN CERTIFICATE-----\n"; 170 | String end_cert = "-----END CERTIFICATE-----"; 171 | 172 | try { 173 | byte[] derCert = cert.getEncoded(); 174 | String pemCertPre = new String(encoder.encode(derCert)); 175 | String pemCert = cert_begin + pemCertPre + end_cert; 176 | return pemCert; 177 | } catch (Exception e) { 178 | // do nothing 179 | return ""; 180 | } 181 | } 182 | 183 | public static byte[] getMD5Checksum(byte[] buffer) throws Exception{ 184 | try { 185 | MessageDigest complete = MessageDigest.getInstance("MD5"); 186 | int numRead = buffer.length; 187 | if (numRead > 0) { 188 | complete.update(buffer, 0, numRead); 189 | } 190 | return complete.digest(); 191 | } catch (Exception e) { 192 | throw new Exception("Error in MD5 checksum computation."); 193 | } 194 | } 195 | } -------------------------------------------------------------------------------- /src/cc/arduino/plugins/wifi101/flashers/java/SSLCertDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WiFi101 Updater Arduino-IDE Plugin. 3 | * Copyright 2016 Arduino LLC (http://www.arduino.cc/) 4 | * 5 | * Arduino is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | * 19 | * As a special exception, you may use this file as part of a free software 20 | * library without restriction. Specifically, if other files instantiate 21 | * templates or use macros or inline functions from this file, or you compile 22 | * this file and link it with other files to produce an executable, this 23 | * file does not by itself cause the resulting executable to be covered by 24 | * the GNU General Public License. This exception does not however 25 | * invalidate any other reasons why the executable file might be covered by 26 | * the GNU General Public License. 27 | */ 28 | package cc.arduino.plugins.wifi101.flashers.java; 29 | 30 | import java.io.FileNotFoundException; 31 | import java.io.IOException; 32 | import java.net.URL; 33 | import java.security.KeyManagementException; 34 | import java.security.NoSuchAlgorithmException; 35 | import java.security.cert.Certificate; 36 | import java.security.cert.CertificateEncodingException; 37 | import java.security.cert.CertificateException; 38 | import java.security.cert.X509Certificate; 39 | 40 | import javax.net.ssl.HttpsURLConnection; 41 | import javax.net.ssl.SSLContext; 42 | import javax.net.ssl.SSLPeerUnverifiedException; 43 | import javax.net.ssl.TrustManager; 44 | import javax.net.ssl.X509TrustManager; 45 | 46 | public class SSLCertDownloader { 47 | 48 | public static Certificate[] retrieveFromURL(URL url) throws NoSuchAlgorithmException, KeyManagementException, 49 | SSLPeerUnverifiedException, CertificateEncodingException, FileNotFoundException, IOException { 50 | 51 | SSLContext ssl = SSLContext.getInstance("TLS"); 52 | ssl.init(null, new TrustManager[] { new X509TrustManager() { 53 | private X509Certificate[] accepted; 54 | 55 | @Override 56 | public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { 57 | } 58 | 59 | @Override 60 | public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { 61 | accepted = xcs; 62 | } 63 | 64 | @Override 65 | public X509Certificate[] getAcceptedIssuers() { 66 | return accepted; 67 | } 68 | } }, null); 69 | 70 | // This is a workaround to reduce the impact of this bug: 71 | // http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8159569 72 | try { 73 | return retireveWithVerification(url, ssl); 74 | } catch (Exception e) { 75 | return retireveWithoutVerification(url, ssl); 76 | } 77 | } 78 | 79 | public static Certificate[] retireveWithVerification(URL url, SSLContext ssl) 80 | throws IOException, SSLPeerUnverifiedException { 81 | HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); 82 | connection.setSSLSocketFactory(ssl.getSocketFactory()); 83 | connection.connect(); 84 | Certificate[] certificates = connection.getServerCertificates(); 85 | connection.disconnect(); 86 | return certificates; 87 | } 88 | 89 | public static Certificate[] retireveWithoutVerification(URL url, SSLContext ssl) 90 | throws IOException, SSLPeerUnverifiedException { 91 | HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); 92 | connection.setHostnameVerifier((str, sess) -> true); 93 | connection.setSSLSocketFactory(ssl.getSocketFactory()); 94 | connection.connect(); 95 | Certificate[] certificates = connection.getServerCertificates(); 96 | connection.disconnect(); 97 | return certificates; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/cc/arduino/plugins/wifi101/flashers/java/WINCFlasher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WiFi101 Updater Arduino-IDE Plugin. 3 | * Copyright 2016 Arduino LLC (http://www.arduino.cc/) 4 | * 5 | * Arduino is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | * 19 | * As a special exception, you may use this file as part of a free software 20 | * library without restriction. Specifically, if other files instantiate 21 | * templates or use macros or inline functions from this file, or you compile 22 | * this file and link it with other files to produce an executable, this 23 | * file does not by itself cause the resulting executable to be covered by 24 | * the GNU General Public License. This exception does not however 25 | * invalidate any other reasons why the executable file might be covered by 26 | * the GNU General Public License. 27 | */ 28 | package cc.arduino.plugins.wifi101.flashers.java; 29 | 30 | import java.net.MalformedURLException; 31 | import java.net.URL; 32 | import java.security.cert.Certificate; 33 | import java.security.cert.X509Certificate; 34 | import java.util.Arrays; 35 | import java.util.List; 36 | 37 | import cc.arduino.plugins.wifi101.certs.WiFi101Certificate; 38 | import cc.arduino.plugins.wifi101.certs.WiFi101CertificateBundle; 39 | import cc.arduino.plugins.wifi101.flashers.Flasher; 40 | 41 | public class WINCFlasher extends Flasher { 42 | 43 | public WINCFlasher(String _modulename, String _version, String _filename, boolean _certavail, int _baudrate, List _compatibleBoard) { 44 | super(_modulename, _version, _filename, _certavail, _baudrate, _compatibleBoard); 45 | } 46 | 47 | @Override 48 | public void updateFirmware(String port) throws Exception { 49 | FlasherSerialClient client = null; 50 | try { 51 | file = openFirmwareFile(); 52 | progress(10, "Connecting to programmer..."); 53 | client = new FlasherSerialClient(); 54 | client.open(port, this.baudrate); 55 | client.hello(); 56 | int maxPayload = client.getMaximumPayload(); 57 | 58 | byte[] fwData = this.getData(); 59 | int size = fwData.length; 60 | int address = 0x00000000; 61 | int written = 0; 62 | 63 | progress(20, "Erasing target..."); 64 | client.eraseFlash(address, size); 65 | 66 | while (written < size) { 67 | progress(20 + written * 40 / size, "Programming " + size + " bytes ..."); 68 | int len = maxPayload; 69 | if (written + len > size) { 70 | len = size - written; 71 | } 72 | client.writeFlash(address, Arrays.copyOfRange(fwData, written, written + len)); 73 | written += len; 74 | address += len; 75 | } 76 | int readed = 0; 77 | address = 0x00000000; 78 | while (readed < size) { 79 | progress(60 + readed * 40 / size, "Verifying..."); 80 | int len = maxPayload; 81 | if (readed + len > size) { 82 | len = size - readed; 83 | } 84 | byte[] data = client.readFlash(address, len); 85 | if (!Arrays.equals(data, Arrays.copyOfRange(fwData, readed, readed + len))) { 86 | throw new Exception("Error during verify at address " + address); 87 | } 88 | readed += len; 89 | address += len; 90 | } 91 | progress(100, "Done!"); 92 | } finally { 93 | if (client != null) { 94 | client.close(); 95 | } 96 | } 97 | } 98 | 99 | @Override 100 | public void uploadCertificates(String port, List websites) throws Exception { 101 | FlasherSerialClient client = null; 102 | try { 103 | progress(10, "Connecting to programmer..."); 104 | client = new FlasherSerialClient(); 105 | client.open(port, this.baudrate); 106 | client.hello(); 107 | int maxPayload = client.getMaximumPayload(); 108 | 109 | progress(20, "Reading section header"); 110 | byte[] startPattern = client.readFlash(0x00004000, 16); 111 | 112 | WiFi101CertificateBundle certBundle = createBundleFromWebsites(websites); 113 | 114 | byte[] certData; 115 | 116 | if (Arrays.equals(WiFi101CertificateBundle.START_PATTERN_V0, startPattern)) { 117 | certData = certBundle.getEncodedV0(); 118 | } else if (Arrays.equals(WiFi101CertificateBundle.START_PATTERN_V1, startPattern)) { 119 | certData = certBundle.getEncodedV1(); 120 | } else { 121 | throw new Exception("Unknown starting pattern, please reflash firmware!"); 122 | } 123 | 124 | int size = certData.length; 125 | int address = 0x00004000; 126 | int written = 0; 127 | 128 | progress(50, "Erasing target..."); 129 | client.eraseFlash(address, size); 130 | 131 | while (written < size) { 132 | progress(60 + written * 80 / size, "Programming..."); 133 | int len = maxPayload; 134 | if (written + len > size) { 135 | len = size - written; 136 | } 137 | client.writeFlash(address, Arrays.copyOfRange(certData, written, written + len)); 138 | written += len; 139 | address += len; 140 | } 141 | progress(100, "Done!"); 142 | } finally { 143 | if (client != null) { 144 | client.close(); 145 | } 146 | } 147 | } 148 | 149 | public WiFi101CertificateBundle createBundleFromWebsites(List websites) throws Exception { 150 | WiFi101CertificateBundle certBundle = new WiFi101CertificateBundle(); 151 | int count = 0; 152 | for (String website : websites) { 153 | URL url; 154 | try { 155 | url = new URL(website); 156 | } catch (MalformedURLException e1) { 157 | url = new URL("https://" + website); 158 | } 159 | 160 | progress(30 + 20 * count / websites.size(), "Downloading certificate from " + website + "..."); 161 | Certificate[] certificates = SSLCertDownloader.retrieveFromURL(url); 162 | 163 | // Pick the latest certificate (that should be the root cert) 164 | X509Certificate x509 = (X509Certificate) certificates[certificates.length - 1]; 165 | 166 | WiFi101Certificate cert = new WiFi101Certificate(x509); 167 | certBundle.add(cert); 168 | } 169 | return certBundle; 170 | } 171 | } 172 | --------------------------------------------------------------------------------